Whamcloud - gitweb
LU-11596 osc: Fix and re-enable sanity grant test for ARM
[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 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11671
61         ALWAYS_EXCEPT+=" 45"
62         # bug number:    LU-14067 LU-14067
63         ALWAYS_EXCEPT+=" 400a     400b"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5              12     8   12  15   (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT+="              "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 if [ "$ost1_FSTYPE" = "zfs" ]; then
89         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
90         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
91 fi
92
93 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_0e() { # LU-13417
255         (( $MDSCOUNT > 1 )) ||
256                 skip "We need at least 2 MDTs for this test"
257
258         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
259                 skip "Need server version at least 2.14.51"
260
261         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
262         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
263
264         [ $default_lmv_count -eq 1 ] ||
265                 error "$MOUNT default stripe count $default_lmv_count"
266
267         [ $default_lmv_index -eq -1 ] ||
268                 error "$MOUNT default stripe index $default_lmv_index"
269
270         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
271         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
272
273         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
274         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
275
276         [ $mdt_index1 -eq $mdt_index2 ] &&
277                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
278
279         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
280 }
281 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
282
283 test_1() {
284         test_mkdir $DIR/$tdir
285         test_mkdir $DIR/$tdir/d2
286         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
287         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
288         rmdir $DIR/$tdir/d2
289         rmdir $DIR/$tdir
290         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
291 }
292 run_test 1 "mkdir; remkdir; rmdir"
293
294 test_2() {
295         test_mkdir $DIR/$tdir
296         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
297         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
298         rm -r $DIR/$tdir
299         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
300 }
301 run_test 2 "mkdir; touch; rmdir; check file"
302
303 test_3() {
304         test_mkdir $DIR/$tdir
305         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
306         touch $DIR/$tdir/$tfile
307         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
308         rm -r $DIR/$tdir
309         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
310 }
311 run_test 3 "mkdir; touch; rmdir; check dir"
312
313 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
314 test_4() {
315         test_mkdir -i 1 $DIR/$tdir
316
317         touch $DIR/$tdir/$tfile ||
318                 error "Create file under remote directory failed"
319
320         rmdir $DIR/$tdir &&
321                 error "Expect error removing in-use dir $DIR/$tdir"
322
323         test -d $DIR/$tdir || error "Remote directory disappeared"
324
325         rm -rf $DIR/$tdir || error "remove remote dir error"
326 }
327 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
328
329 test_5() {
330         test_mkdir $DIR/$tdir
331         test_mkdir $DIR/$tdir/d2
332         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
333         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
334         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
335 }
336 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
337
338 test_6a() {
339         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
340         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
341         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
342                 error "$tfile does not have perm 0666 or UID $UID"
343         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
344         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
345                 error "$tfile should be 0666 and owned by UID $UID"
346 }
347 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
348
349 test_6c() {
350         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
351
352         touch $DIR/$tfile
353         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
354         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
355                 error "$tfile should be owned by UID $RUNAS_ID"
356         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
357         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
358                 error "$tfile should be owned by UID $RUNAS_ID"
359 }
360 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
361
362 test_6e() {
363         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
364
365         touch $DIR/$tfile
366         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
367         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
368                 error "$tfile should be owned by GID $UID"
369         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
370         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
371                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
372 }
373 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
374
375 test_6g() {
376         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
377
378         test_mkdir $DIR/$tdir
379         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
380         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
381         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
382         test_mkdir $DIR/$tdir/d/subdir
383         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
384                 error "$tdir/d/subdir should be GID $RUNAS_GID"
385         if [[ $MDSCOUNT -gt 1 ]]; then
386                 # check remote dir sgid inherite
387                 $LFS mkdir -i 0 $DIR/$tdir.local ||
388                         error "mkdir $tdir.local failed"
389                 chmod g+s $DIR/$tdir.local ||
390                         error "chmod $tdir.local failed"
391                 chgrp $RUNAS_GID $DIR/$tdir.local ||
392                         error "chgrp $tdir.local failed"
393                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
394                         error "mkdir $tdir.remote failed"
395                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
396                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
397                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be mode 02755"
399         fi
400 }
401 run_test 6g "verify new dir in sgid dir inherits group"
402
403 test_6h() { # bug 7331
404         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
405
406         touch $DIR/$tfile || error "touch failed"
407         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
408         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
409                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
410         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
411                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
412 }
413 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
414
415 test_7a() {
416         test_mkdir $DIR/$tdir
417         $MCREATE $DIR/$tdir/$tfile
418         chmod 0666 $DIR/$tdir/$tfile
419         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
420                 error "$tdir/$tfile should be mode 0666"
421 }
422 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
423
424 test_7b() {
425         if [ ! -d $DIR/$tdir ]; then
426                 test_mkdir $DIR/$tdir
427         fi
428         $MCREATE $DIR/$tdir/$tfile
429         echo -n foo > $DIR/$tdir/$tfile
430         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
431         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
432 }
433 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
434
435 test_8() {
436         test_mkdir $DIR/$tdir
437         touch $DIR/$tdir/$tfile
438         chmod 0666 $DIR/$tdir/$tfile
439         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
440                 error "$tfile mode not 0666"
441 }
442 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
443
444 test_9() {
445         test_mkdir $DIR/$tdir
446         test_mkdir $DIR/$tdir/d2
447         test_mkdir $DIR/$tdir/d2/d3
448         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
449 }
450 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
451
452 test_10() {
453         test_mkdir $DIR/$tdir
454         test_mkdir $DIR/$tdir/d2
455         touch $DIR/$tdir/d2/$tfile
456         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
457                 error "$tdir/d2/$tfile not a file"
458 }
459 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
460
461 test_11() {
462         test_mkdir $DIR/$tdir
463         test_mkdir $DIR/$tdir/d2
464         chmod 0666 $DIR/$tdir/d2
465         chmod 0705 $DIR/$tdir/d2
466         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
467                 error "$tdir/d2 mode not 0705"
468 }
469 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
470
471 test_12() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         chmod 0666 $DIR/$tdir/$tfile
475         chmod 0654 $DIR/$tdir/$tfile
476         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
477                 error "$tdir/d2 mode not 0654"
478 }
479 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
480
481 test_13() {
482         test_mkdir $DIR/$tdir
483         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
484         >  $DIR/$tdir/$tfile
485         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
486                 error "$tdir/$tfile size not 0 after truncate"
487 }
488 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
489
490 test_14() {
491         test_mkdir $DIR/$tdir
492         touch $DIR/$tdir/$tfile
493         rm $DIR/$tdir/$tfile
494         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
495 }
496 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
497
498 test_15() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
502         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
503                 error "$tdir/${tfile_2} not a file after rename"
504         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
505 }
506 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
507
508 test_16() {
509         test_mkdir $DIR/$tdir
510         touch $DIR/$tdir/$tfile
511         rm -rf $DIR/$tdir/$tfile
512         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
513 }
514 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
515
516 test_17a() {
517         test_mkdir $DIR/$tdir
518         touch $DIR/$tdir/$tfile
519         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
520         ls -l $DIR/$tdir
521         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
522                 error "$tdir/l-exist not a symlink"
523         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not referencing a file"
525         rm -f $DIR/$tdir/l-exist
526         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
527 }
528 run_test 17a "symlinks: create, remove (real)"
529
530 test_17b() {
531         test_mkdir $DIR/$tdir
532         ln -s no-such-file $DIR/$tdir/l-dangle
533         ls -l $DIR/$tdir
534         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
535                 error "$tdir/l-dangle not referencing no-such-file"
536         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing non-existent file"
538         rm -f $DIR/$tdir/l-dangle
539         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
540 }
541 run_test 17b "symlinks: create, remove (dangling)"
542
543 test_17c() { # bug 3440 - don't save failed open RPC for replay
544         test_mkdir $DIR/$tdir
545         ln -s foo $DIR/$tdir/$tfile
546         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
547 }
548 run_test 17c "symlinks: open dangling (should return error)"
549
550 test_17d() {
551         test_mkdir $DIR/$tdir
552         ln -s foo $DIR/$tdir/$tfile
553         touch $DIR/$tdir/$tfile || error "creating to new symlink"
554 }
555 run_test 17d "symlinks: create dangling"
556
557 test_17e() {
558         test_mkdir $DIR/$tdir
559         local foo=$DIR/$tdir/$tfile
560         ln -s $foo $foo || error "create symlink failed"
561         ls -l $foo || error "ls -l failed"
562         ls $foo && error "ls not failed" || true
563 }
564 run_test 17e "symlinks: create recursive symlink (should return error)"
565
566 test_17f() {
567         test_mkdir $DIR/$tdir
568         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
569         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
570         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
573         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
574         ls -l  $DIR/$tdir
575 }
576 run_test 17f "symlinks: long and very long symlink name"
577
578 # str_repeat(S, N) generate a string that is string S repeated N times
579 str_repeat() {
580         local s=$1
581         local n=$2
582         local ret=''
583         while [ $((n -= 1)) -ge 0 ]; do
584                 ret=$ret$s
585         done
586         echo $ret
587 }
588
589 # Long symlinks and LU-2241
590 test_17g() {
591         test_mkdir $DIR/$tdir
592         local TESTS="59 60 61 4094 4095"
593
594         # Fix for inode size boundary in 2.1.4
595         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
596                 TESTS="4094 4095"
597
598         # Patch not applied to 2.2 or 2.3 branches
599         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
600         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
601                 TESTS="4094 4095"
602
603         for i in $TESTS; do
604                 local SYMNAME=$(str_repeat 'x' $i)
605                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
606                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
607         done
608 }
609 run_test 17g "symlinks: really long symlink name and inode boundaries"
610
611 test_17h() { #bug 17378
612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
613         remote_mds_nodsh && skip "remote MDS with nodsh"
614
615         local mdt_idx
616
617         test_mkdir $DIR/$tdir
618         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
619         $LFS setstripe -c -1 $DIR/$tdir
620         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
621         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
622         touch $DIR/$tdir/$tfile || true
623 }
624 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
625
626 test_17i() { #bug 20018
627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
628         remote_mds_nodsh && skip "remote MDS with nodsh"
629
630         local foo=$DIR/$tdir/$tfile
631         local mdt_idx
632
633         test_mkdir -c1 $DIR/$tdir
634         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
635         ln -s $foo $foo || error "create symlink failed"
636 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
637         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
638         ls -l $foo && error "error not detected"
639         return 0
640 }
641 run_test 17i "don't panic on short symlink (should return error)"
642
643 test_17k() { #bug 22301
644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
645         [[ -z "$(which rsync 2>/dev/null)" ]] &&
646                 skip "no rsync command"
647         rsync --help | grep -q xattr ||
648                 skip_env "$(rsync --version | head -n1) does not support xattrs"
649         test_mkdir $DIR/$tdir
650         test_mkdir $DIR/$tdir.new
651         touch $DIR/$tdir/$tfile
652         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
653         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
654                 error "rsync failed with xattrs enabled"
655 }
656 run_test 17k "symlinks: rsync with xattrs enabled"
657
658 test_17l() { # LU-279
659         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
660                 skip "no getfattr command"
661
662         test_mkdir $DIR/$tdir
663         touch $DIR/$tdir/$tfile
664         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
665         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
666                 # -h to not follow symlinks. -m '' to list all the xattrs.
667                 # grep to remove first line: '# file: $path'.
668                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
669                 do
670                         lgetxattr_size_check $path $xattr ||
671                                 error "lgetxattr_size_check $path $xattr failed"
672                 done
673         done
674 }
675 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
676
677 # LU-1540
678 test_17m() {
679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
680         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
681         remote_mds_nodsh && skip "remote MDS with nodsh"
682         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
683         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
684                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
685
686         local short_sym="0123456789"
687         local wdir=$DIR/$tdir
688         local i
689
690         test_mkdir $wdir
691         long_sym=$short_sym
692         # create a long symlink file
693         for ((i = 0; i < 4; ++i)); do
694                 long_sym=${long_sym}${long_sym}
695         done
696
697         echo "create 512 short and long symlink files under $wdir"
698         for ((i = 0; i < 256; ++i)); do
699                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
700                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
701         done
702
703         echo "erase them"
704         rm -f $wdir/*
705         sync
706         wait_delete_completed
707
708         echo "recreate the 512 symlink files with a shorter string"
709         for ((i = 0; i < 512; ++i)); do
710                 # rewrite the symlink file with a shorter string
711                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
712                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
713         done
714
715         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
716         local devname=$(mdsdevname $mds_index)
717
718         echo "stop and checking mds${mds_index}:"
719         # e2fsck should not return error
720         stop mds${mds_index}
721         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
722         rc=$?
723
724         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
725                 error "start mds${mds_index} failed"
726         df $MOUNT > /dev/null 2>&1
727         [ $rc -eq 0 ] ||
728                 error "e2fsck detected error for short/long symlink: rc=$rc"
729         rm -f $wdir/*
730 }
731 run_test 17m "run e2fsck against MDT which contains short/long symlink"
732
733 check_fs_consistency_17n() {
734         local mdt_index
735         local rc=0
736
737         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
738         # so it only check MDT1/MDT2 instead of all of MDTs.
739         for mdt_index in 1 2; do
740                 local devname=$(mdsdevname $mdt_index)
741                 # e2fsck should not return error
742                 stop mds${mdt_index}
743                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
744                         rc=$((rc + $?))
745
746                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
747                         error "mount mds$mdt_index failed"
748                 df $MOUNT > /dev/null 2>&1
749         done
750         return $rc
751 }
752
753 test_17n() {
754         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
756         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
757         remote_mds_nodsh && skip "remote MDS with nodsh"
758         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
759         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
760                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
761
762         local i
763
764         test_mkdir $DIR/$tdir
765         for ((i=0; i<10; i++)); do
766                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
767                         error "create remote dir error $i"
768                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
769                         error "create files under remote dir failed $i"
770         done
771
772         check_fs_consistency_17n ||
773                 error "e2fsck report error after create files under remote dir"
774
775         for ((i = 0; i < 10; i++)); do
776                 rm -rf $DIR/$tdir/remote_dir_${i} ||
777                         error "destroy remote dir error $i"
778         done
779
780         check_fs_consistency_17n ||
781                 error "e2fsck report error after unlink files under remote dir"
782
783         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
784                 skip "lustre < 2.4.50 does not support migrate mv"
785
786         for ((i = 0; i < 10; i++)); do
787                 mkdir -p $DIR/$tdir/remote_dir_${i}
788                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
789                         error "create files under remote dir failed $i"
790                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
791                         error "migrate remote dir error $i"
792         done
793         check_fs_consistency_17n || error "e2fsck report error after migration"
794
795         for ((i = 0; i < 10; i++)); do
796                 rm -rf $DIR/$tdir/remote_dir_${i} ||
797                         error "destroy remote dir error $i"
798         done
799
800         check_fs_consistency_17n || error "e2fsck report error after unlink"
801 }
802 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
803
804 test_17o() {
805         remote_mds_nodsh && skip "remote MDS with nodsh"
806         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
807                 skip "Need MDS version at least 2.3.64"
808
809         local wdir=$DIR/${tdir}o
810         local mdt_index
811         local rc=0
812
813         test_mkdir $wdir
814         touch $wdir/$tfile
815         mdt_index=$($LFS getstripe -m $wdir/$tfile)
816         mdt_index=$((mdt_index + 1))
817
818         cancel_lru_locks mdc
819         #fail mds will wait the failover finish then set
820         #following fail_loc to avoid interfer the recovery process.
821         fail mds${mdt_index}
822
823         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
824         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
825         ls -l $wdir/$tfile && rc=1
826         do_facet mds${mdt_index} lctl set_param fail_loc=0
827         [[ $rc -eq 0 ]] || error "stat file should fail"
828 }
829 run_test 17o "stat file with incompat LMA feature"
830
831 test_18() {
832         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
833         ls $DIR || error "Failed to ls $DIR: $?"
834 }
835 run_test 18 "touch .../f ; ls ... =============================="
836
837 test_19a() {
838         touch $DIR/$tfile
839         ls -l $DIR
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
844
845 test_19b() {
846         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
847 }
848 run_test 19b "ls -l .../f19 (should return error) =============="
849
850 test_19c() {
851         [ $RUNAS_ID -eq $UID ] &&
852                 skip_env "RUNAS_ID = UID = $UID -- skipping"
853
854         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
855 }
856 run_test 19c "$RUNAS touch .../f19 (should return error) =="
857
858 test_19d() {
859         cat $DIR/f19 && error || true
860 }
861 run_test 19d "cat .../f19 (should return error) =============="
862
863 test_20() {
864         touch $DIR/$tfile
865         rm $DIR/$tfile
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
871 }
872 run_test 20 "touch .../f ; ls -l ..."
873
874 test_21() {
875         test_mkdir $DIR/$tdir
876         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
877         ln -s dangle $DIR/$tdir/link
878         echo foo >> $DIR/$tdir/link
879         cat $DIR/$tdir/dangle
880         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
881         $CHECKSTAT -f -t file $DIR/$tdir/link ||
882                 error "$tdir/link not linked to a file"
883 }
884 run_test 21 "write to dangling link"
885
886 test_22() {
887         local wdir=$DIR/$tdir
888         test_mkdir $wdir
889         chown $RUNAS_ID:$RUNAS_GID $wdir
890         (cd $wdir || error "cd $wdir failed";
891                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
892                 $RUNAS tar xf -)
893         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
894         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
895         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
896                 error "checkstat -u failed"
897 }
898 run_test 22 "unpack tar archive as non-root user"
899
900 # was test_23
901 test_23a() {
902         test_mkdir $DIR/$tdir
903         local file=$DIR/$tdir/$tfile
904
905         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
906         openfile -f O_CREAT:O_EXCL $file &&
907                 error "$file recreate succeeded" || true
908 }
909 run_test 23a "O_CREAT|O_EXCL in subdir"
910
911 test_23b() { # bug 18988
912         test_mkdir $DIR/$tdir
913         local file=$DIR/$tdir/$tfile
914
915         rm -f $file
916         echo foo > $file || error "write filed"
917         echo bar >> $file || error "append filed"
918         $CHECKSTAT -s 8 $file || error "wrong size"
919         rm $file
920 }
921 run_test 23b "O_APPEND check"
922
923 # LU-9409, size with O_APPEND and tiny writes
924 test_23c() {
925         local file=$DIR/$tfile
926
927         # single dd
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
929         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
930         rm -f $file
931
932         # racing tiny writes
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
935         wait
936         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
937         rm -f $file
938
939         #racing tiny & normal writes
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
941         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
942         wait
943         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
944         rm -f $file
945
946         #racing tiny & normal writes 2, ugly numbers
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
948         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
949         wait
950         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
951         rm -f $file
952 }
953 run_test 23c "O_APPEND size checks for tiny writes"
954
955 # LU-11069 file offset is correct after appending writes
956 test_23d() {
957         local file=$DIR/$tfile
958         local offset
959
960         echo CentaurHauls > $file
961         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
962         if ((offset != 26)); then
963                 error "wrong offset, expected 26, got '$offset'"
964         fi
965 }
966 run_test 23d "file offset is correct after appending writes"
967
968 # rename sanity
969 test_24a() {
970         echo '-- same directory rename'
971         test_mkdir $DIR/$tdir
972         touch $DIR/$tdir/$tfile.1
973         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
974         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
975 }
976 run_test 24a "rename file to non-existent target"
977
978 test_24b() {
979         test_mkdir $DIR/$tdir
980         touch $DIR/$tdir/$tfile.{1,2}
981         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
982         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
983         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
984 }
985 run_test 24b "rename file to existing target"
986
987 test_24c() {
988         test_mkdir $DIR/$tdir
989         test_mkdir $DIR/$tdir/d$testnum.1
990         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
991         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
992         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
993 }
994 run_test 24c "rename directory to non-existent target"
995
996 test_24d() {
997         test_mkdir -c1 $DIR/$tdir
998         test_mkdir -c1 $DIR/$tdir/d$testnum.1
999         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1000         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1001         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1002         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1003 }
1004 run_test 24d "rename directory to existing target"
1005
1006 test_24e() {
1007         echo '-- cross directory renames --'
1008         test_mkdir $DIR/R5a
1009         test_mkdir $DIR/R5b
1010         touch $DIR/R5a/f
1011         mv $DIR/R5a/f $DIR/R5b/g
1012         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1013         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1014 }
1015 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1016
1017 test_24f() {
1018         test_mkdir $DIR/R6a
1019         test_mkdir $DIR/R6b
1020         touch $DIR/R6a/f $DIR/R6b/g
1021         mv $DIR/R6a/f $DIR/R6b/g
1022         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1023         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1024 }
1025 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1026
1027 test_24g() {
1028         test_mkdir $DIR/R7a
1029         test_mkdir $DIR/R7b
1030         test_mkdir $DIR/R7a/d
1031         mv $DIR/R7a/d $DIR/R7b/e
1032         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1033         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1034 }
1035 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1036
1037 test_24h() {
1038         test_mkdir -c1 $DIR/R8a
1039         test_mkdir -c1 $DIR/R8b
1040         test_mkdir -c1 $DIR/R8a/d
1041         test_mkdir -c1 $DIR/R8b/e
1042         mrename $DIR/R8a/d $DIR/R8b/e
1043         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1044         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1045 }
1046 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1047
1048 test_24i() {
1049         echo "-- rename error cases"
1050         test_mkdir $DIR/R9
1051         test_mkdir $DIR/R9/a
1052         touch $DIR/R9/f
1053         mrename $DIR/R9/f $DIR/R9/a
1054         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1055         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1056         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1057 }
1058 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1059
1060 test_24j() {
1061         test_mkdir $DIR/R10
1062         mrename $DIR/R10/f $DIR/R10/g
1063         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1064         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1065         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1066 }
1067 run_test 24j "source does not exist ============================"
1068
1069 test_24k() {
1070         test_mkdir $DIR/R11a
1071         test_mkdir $DIR/R11a/d
1072         touch $DIR/R11a/f
1073         mv $DIR/R11a/f $DIR/R11a/d
1074         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1075         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1076 }
1077 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1078
1079 # bug 2429 - rename foo foo foo creates invalid file
1080 test_24l() {
1081         f="$DIR/f24l"
1082         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1083 }
1084 run_test 24l "Renaming a file to itself ========================"
1085
1086 test_24m() {
1087         f="$DIR/f24m"
1088         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1089         # on ext3 this does not remove either the source or target files
1090         # though the "expected" operation would be to remove the source
1091         $CHECKSTAT -t file ${f} || error "${f} missing"
1092         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1093 }
1094 run_test 24m "Renaming a file to a hard link to itself ========="
1095
1096 test_24n() {
1097     f="$DIR/f24n"
1098     # this stats the old file after it was renamed, so it should fail
1099     touch ${f}
1100     $CHECKSTAT ${f} || error "${f} missing"
1101     mv ${f} ${f}.rename
1102     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1103     $CHECKSTAT -a ${f} || error "${f} exists"
1104 }
1105 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1106
1107 test_24o() {
1108         test_mkdir $DIR/$tdir
1109         rename_many -s random -v -n 10 $DIR/$tdir
1110 }
1111 run_test 24o "rename of files during htree split"
1112
1113 test_24p() {
1114         test_mkdir $DIR/R12a
1115         test_mkdir $DIR/R12b
1116         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1117         mrename $DIR/R12a $DIR/R12b
1118         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1119         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1120         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1121         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1122 }
1123 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1124
1125 cleanup_multiop_pause() {
1126         trap 0
1127         kill -USR1 $MULTIPID
1128 }
1129
1130 test_24q() {
1131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1132
1133         test_mkdir $DIR/R13a
1134         test_mkdir $DIR/R13b
1135         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1136         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1137         MULTIPID=$!
1138
1139         trap cleanup_multiop_pause EXIT
1140         mrename $DIR/R13a $DIR/R13b
1141         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1142         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1143         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1144         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1145         cleanup_multiop_pause
1146         wait $MULTIPID || error "multiop close failed"
1147 }
1148 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1149
1150 test_24r() { #bug 3789
1151         test_mkdir $DIR/R14a
1152         test_mkdir $DIR/R14a/b
1153         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1154         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1155         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1156 }
1157 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1158
1159 test_24s() {
1160         test_mkdir $DIR/R15a
1161         test_mkdir $DIR/R15a/b
1162         test_mkdir $DIR/R15a/b/c
1163         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1164         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1165         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1166 }
1167 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1168 test_24t() {
1169         test_mkdir $DIR/R16a
1170         test_mkdir $DIR/R16a/b
1171         test_mkdir $DIR/R16a/b/c
1172         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1173         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1174         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1175 }
1176 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1177
1178 test_24u() { # bug12192
1179         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1180         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1181 }
1182 run_test 24u "create stripe file"
1183
1184 simple_cleanup_common() {
1185         local createmany=$1
1186         local rc=0
1187
1188         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1189
1190         local start=$SECONDS
1191
1192         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1193         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1194         rc=$?
1195         wait_delete_completed
1196         echo "cleanup time $((SECONDS - start))"
1197         return $rc
1198 }
1199
1200 max_pages_per_rpc() {
1201         local mdtname="$(printf "MDT%04x" ${1:-0})"
1202         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1203 }
1204
1205 test_24v() {
1206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1207
1208         local nrfiles=${COUNT:-100000}
1209         local fname="$DIR/$tdir/$tfile"
1210
1211         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1212         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1213
1214         test_mkdir "$(dirname $fname)"
1215         # assume MDT0000 has the fewest inodes
1216         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1217         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1218         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1219
1220         stack_trap "simple_cleanup_common $nrfiles"
1221
1222         createmany -m "$fname" $nrfiles
1223
1224         cancel_lru_locks mdc
1225         lctl set_param mdc.*.stats clear
1226
1227         # was previously test_24D: LU-6101
1228         # readdir() returns correct number of entries after cursor reload
1229         local num_ls=$(ls $DIR/$tdir | wc -l)
1230         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1231         local num_all=$(ls -a $DIR/$tdir | wc -l)
1232         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1233                 [ $num_all -ne $((nrfiles + 2)) ]; then
1234                         error "Expected $nrfiles files, got $num_ls " \
1235                                 "($num_uniq unique $num_all .&..)"
1236         fi
1237         # LU-5 large readdir
1238         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1239         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1240         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1241         # take into account of overhead in lu_dirpage header and end mark in
1242         # each page, plus one in rpc_num calculation.
1243         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1244         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1245         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1246         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1247         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1248         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1249         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1250         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1251                 error "large readdir doesn't take effect: " \
1252                       "$mds_readpage should be about $rpc_max"
1253 }
1254 run_test 24v "list large directory (test hash collision, b=17560)"
1255
1256 test_24w() { # bug21506
1257         SZ1=234852
1258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1259         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1260         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1261         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1262         [[ "$SZ1" -eq "$SZ2" ]] ||
1263                 error "Error reading at the end of the file $tfile"
1264 }
1265 run_test 24w "Reading a file larger than 4Gb"
1266
1267 test_24x() {
1268         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1270         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1271                 skip "Need MDS version at least 2.7.56"
1272
1273         local MDTIDX=1
1274         local remote_dir=$DIR/$tdir/remote_dir
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $MDTIDX $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $DIR/$tdir/src_dir
1281         touch $DIR/$tdir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename dir cross MDT failed!"
1287
1288         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1289                 error "rename file cross MDT failed!"
1290
1291         touch $DIR/$tdir/ln_file
1292         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1293                 error "ln file cross MDT failed"
1294
1295         rm -rf $DIR/$tdir || error "Can not delete directories"
1296 }
1297 run_test 24x "cross MDT rename/link"
1298
1299 test_24y() {
1300         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1302
1303         local remote_dir=$DIR/$tdir/remote_dir
1304         local mdtidx=1
1305
1306         test_mkdir $DIR/$tdir
1307         $LFS mkdir -i $mdtidx $remote_dir ||
1308                 error "create remote directory failed"
1309
1310         test_mkdir $remote_dir/src_dir
1311         touch $remote_dir/src_file
1312         test_mkdir $remote_dir/tgt_dir
1313         touch $remote_dir/tgt_file
1314
1315         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1316                 error "rename subdir in the same remote dir failed!"
1317
1318         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1319                 error "rename files in the same remote dir failed!"
1320
1321         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1322                 error "link files in the same remote dir failed!"
1323
1324         rm -rf $DIR/$tdir || error "Can not delete directories"
1325 }
1326 run_test 24y "rename/link on the same dir should succeed"
1327
1328 test_24z() {
1329         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1330         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1331                 skip "Need MDS version at least 2.12.51"
1332
1333         local index
1334
1335         for index in 0 1; do
1336                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1337                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1338         done
1339
1340         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1341
1342         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1343         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1344
1345         local mdts=$(comma_list $(mdts_nodes))
1346
1347         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1348         stack_trap "do_nodes $mdts $LCTL \
1349                 set_param mdt.*.enable_remote_rename=1" EXIT
1350
1351         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1352
1353         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1354         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1355 }
1356 run_test 24z "cross-MDT rename is done as cp"
1357
1358 test_24A() { # LU-3182
1359         local NFILES=5000
1360
1361         test_mkdir $DIR/$tdir
1362         stack_trap "simple_cleanup_common $NFILES"
1363         createmany -m $DIR/$tdir/$tfile $NFILES
1364         local t=$(ls $DIR/$tdir | wc -l)
1365         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1366         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1367
1368         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1369                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1370 }
1371 run_test 24A "readdir() returns correct number of entries."
1372
1373 test_24B() { # LU-4805
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         local count
1377
1378         test_mkdir $DIR/$tdir
1379         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1380                 error "create striped dir failed"
1381
1382         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1383         [ $count -eq 2 ] || error "Expected 2, got $count"
1384
1385         touch $DIR/$tdir/striped_dir/a
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 3 ] || error "Expected 3, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/.f
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 4 ] || error "Expected 4, got $count"
1394
1395         rm -rf $DIR/$tdir || error "Can not delete directories"
1396 }
1397 run_test 24B "readdir for striped dir return correct number of entries"
1398
1399 test_24C() {
1400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1401
1402         mkdir $DIR/$tdir
1403         mkdir $DIR/$tdir/d0
1404         mkdir $DIR/$tdir/d1
1405
1406         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1407                 error "create striped dir failed"
1408
1409         cd $DIR/$tdir/d0/striped_dir
1410
1411         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1412         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1413         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1414
1415         [ "$d0_ino" = "$parent_ino" ] ||
1416                 error ".. wrong, expect $d0_ino, get $parent_ino"
1417
1418         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1419                 error "mv striped dir failed"
1420
1421         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1422
1423         [ "$d1_ino" = "$parent_ino" ] ||
1424                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1425 }
1426 run_test 24C "check .. in striped dir"
1427
1428 test_24E() {
1429         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1431
1432         mkdir -p $DIR/$tdir
1433         mkdir $DIR/$tdir/src_dir
1434         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1435                 error "create remote source failed"
1436
1437         touch $DIR/$tdir/src_dir/src_child/a
1438
1439         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1440                 error "create remote target dir failed"
1441
1442         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1443                 error "create remote target child failed"
1444
1445         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1446                 error "rename dir cross MDT failed!"
1447
1448         find $DIR/$tdir
1449
1450         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1451                 error "src_child still exists after rename"
1452
1453         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1454                 error "missing file(a) after rename"
1455
1456         rm -rf $DIR/$tdir || error "Can not delete directories"
1457 }
1458 run_test 24E "cross MDT rename/link"
1459
1460 test_24F () {
1461         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1462
1463         local repeats=1000
1464         [ "$SLOW" = "no" ] && repeats=100
1465
1466         mkdir -p $DIR/$tdir
1467
1468         echo "$repeats repeats"
1469         for ((i = 0; i < repeats; i++)); do
1470                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1471                 touch $DIR/$tdir/test/a || error "touch fails"
1472                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1473                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1474         done
1475
1476         true
1477 }
1478 run_test 24F "hash order vs readdir (LU-11330)"
1479
1480 test_24G () {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482
1483         local ino1
1484         local ino2
1485
1486         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1487         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1488         touch $DIR/$tdir-0/f1 || error "touch f1"
1489         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1490         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1491         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1492         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1493         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1494 }
1495 run_test 24G "migrate symlink in rename"
1496
1497 test_25a() {
1498         echo '== symlink sanity ============================================='
1499
1500         test_mkdir $DIR/d25
1501         ln -s d25 $DIR/s25
1502         touch $DIR/s25/foo ||
1503                 error "File creation in symlinked directory failed"
1504 }
1505 run_test 25a "create file in symlinked directory ==============="
1506
1507 test_25b() {
1508         [ ! -d $DIR/d25 ] && test_25a
1509         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1510 }
1511 run_test 25b "lookup file in symlinked directory ==============="
1512
1513 test_26a() {
1514         test_mkdir $DIR/d26
1515         test_mkdir $DIR/d26/d26-2
1516         ln -s d26/d26-2 $DIR/s26
1517         touch $DIR/s26/foo || error "File creation failed"
1518 }
1519 run_test 26a "multiple component symlink ======================="
1520
1521 test_26b() {
1522         test_mkdir -p $DIR/$tdir/d26-2
1523         ln -s $tdir/d26-2/foo $DIR/s26-2
1524         touch $DIR/s26-2 || error "File creation failed"
1525 }
1526 run_test 26b "multiple component symlink at end of lookup ======"
1527
1528 test_26c() {
1529         test_mkdir $DIR/d26.2
1530         touch $DIR/d26.2/foo
1531         ln -s d26.2 $DIR/s26.2-1
1532         ln -s s26.2-1 $DIR/s26.2-2
1533         ln -s s26.2-2 $DIR/s26.2-3
1534         chmod 0666 $DIR/s26.2-3/foo
1535 }
1536 run_test 26c "chain of symlinks"
1537
1538 # recursive symlinks (bug 439)
1539 test_26d() {
1540         ln -s d26-3/foo $DIR/d26-3
1541 }
1542 run_test 26d "create multiple component recursive symlink"
1543
1544 test_26e() {
1545         [ ! -h $DIR/d26-3 ] && test_26d
1546         rm $DIR/d26-3
1547 }
1548 run_test 26e "unlink multiple component recursive symlink"
1549
1550 # recursive symlinks (bug 7022)
1551 test_26f() {
1552         test_mkdir $DIR/$tdir
1553         test_mkdir $DIR/$tdir/$tfile
1554         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1555         test_mkdir -p lndir/bar1
1556         test_mkdir $DIR/$tdir/$tfile/$tfile
1557         cd $tfile                || error "cd $tfile failed"
1558         ln -s .. dotdot          || error "ln dotdot failed"
1559         ln -s dotdot/lndir lndir || error "ln lndir failed"
1560         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1561         output=`ls $tfile/$tfile/lndir/bar1`
1562         [ "$output" = bar1 ] && error "unexpected output"
1563         rm -r $tfile             || error "rm $tfile failed"
1564         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1565 }
1566 run_test 26f "rm -r of a directory which has recursive symlink"
1567
1568 test_27a() {
1569         test_mkdir $DIR/$tdir
1570         $LFS getstripe $DIR/$tdir
1571         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1572         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1573         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1574 }
1575 run_test 27a "one stripe file"
1576
1577 test_27b() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1579
1580         test_mkdir $DIR/$tdir
1581         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1582         $LFS getstripe -c $DIR/$tdir/$tfile
1583         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1584                 error "two-stripe file doesn't have two stripes"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1587 }
1588 run_test 27b "create and write to two stripe file"
1589
1590 # 27c family tests specific striping, setstripe -o
1591 test_27ca() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         test_mkdir -p $DIR/$tdir
1594         local osts="1"
1595
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1597         $LFS getstripe -i $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1599                 error "stripe not on specified OST"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27ca "one stripe on specified OST"
1604
1605 test_27cb() {
1606         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1607         test_mkdir -p $DIR/$tdir
1608         local osts="1,0"
1609         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1610         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1611         echo "$getstripe"
1612
1613         # Strip getstripe output to a space separated list of OSTs
1614         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1615                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1616         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1617                 error "stripes not on specified OSTs"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27cb "two stripes on specified OSTs"
1622
1623 test_27cc() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1626                 skip "server does not support overstriping"
1627
1628         test_mkdir -p $DIR/$tdir
1629         local osts="0,0"
1630         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1631         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1632         echo "$getstripe"
1633
1634         # Strip getstripe output to a space separated list of OSTs
1635         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1636                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1637         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1638                 error "stripes not on specified OSTs"
1639
1640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1641 }
1642 run_test 27cc "two stripes on the same OST"
1643
1644 test_27cd() {
1645         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1646         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1647                 skip "server does not support overstriping"
1648         test_mkdir -p $DIR/$tdir
1649         local osts="0,1,1,0"
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27cd "four stripes on two OSTs"
1663
1664 test_27ce() {
1665         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1666                 skip_env "too many osts, skipping"
1667         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1668                 skip "server does not support overstriping"
1669         # We do one more stripe than we have OSTs
1670         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1671                 skip_env "ea_inode feature disabled"
1672
1673         test_mkdir -p $DIR/$tdir
1674         local osts=""
1675         for i in $(seq 0 $OSTCOUNT);
1676         do
1677                 osts=$osts"0"
1678                 if [ $i -ne $OSTCOUNT ]; then
1679                         osts=$osts","
1680                 fi
1681         done
1682         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1683         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1684         echo "$getstripe"
1685
1686         # Strip getstripe output to a space separated list of OSTs
1687         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1688                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1689         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1690                 error "stripes not on specified OSTs"
1691
1692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1693 }
1694 run_test 27ce "more stripes than OSTs with -o"
1695
1696 test_27cf() {
1697         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1698         local pid=0
1699
1700         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1702         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1704                 error "failed to set $osp_proc=0"
1705
1706         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1707         pid=$!
1708         sleep 1
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1710         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1711                 error "failed to set $osp_proc=1"
1712         wait $pid
1713         [[ $pid -ne 0 ]] ||
1714                 error "should return error due to $osp_proc=0"
1715 }
1716 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1717
1718 test_27d() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1721                 error "setstripe failed"
1722         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1724 }
1725 run_test 27d "create file with default settings"
1726
1727 test_27e() {
1728         # LU-5839 adds check for existed layout before setting it
1729         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1730                 skip "Need MDS version at least 2.7.56"
1731
1732         test_mkdir $DIR/$tdir
1733         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1735         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1736 }
1737 run_test 27e "setstripe existing file (should return error)"
1738
1739 test_27f() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1742                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1743         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1744                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1746         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1747 }
1748 run_test 27f "setstripe with bad stripe size (should return error)"
1749
1750 test_27g() {
1751         test_mkdir $DIR/$tdir
1752         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1753         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1754                 error "$DIR/$tdir/$tfile has object"
1755 }
1756 run_test 27g "$LFS getstripe with no objects"
1757
1758 test_27ga() {
1759         test_mkdir $DIR/$tdir
1760         touch $DIR/$tdir/$tfile || error "touch failed"
1761         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1762         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1763         local rc=$?
1764         (( rc == 2 )) || error "getstripe did not return ENOENT"
1765 }
1766 run_test 27ga "$LFS getstripe with missing file (should return error)"
1767
1768 test_27i() {
1769         test_mkdir $DIR/$tdir
1770         touch $DIR/$tdir/$tfile || error "touch failed"
1771         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1772                 error "missing objects"
1773 }
1774 run_test 27i "$LFS getstripe with some objects"
1775
1776 test_27j() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1779                 error "setstripe failed" || true
1780 }
1781 run_test 27j "setstripe with bad stripe offset (should return error)"
1782
1783 test_27k() { # bug 2844
1784         test_mkdir $DIR/$tdir
1785         local file=$DIR/$tdir/$tfile
1786         local ll_max_blksize=$((4 * 1024 * 1024))
1787         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1788         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1789         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1790         dd if=/dev/zero of=$file bs=4k count=1
1791         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1792         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1793 }
1794 run_test 27k "limit i_blksize for broken user apps"
1795
1796 test_27l() {
1797         mcreate $DIR/$tfile || error "creating file"
1798         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1799                 error "setstripe should have failed" || true
1800 }
1801 run_test 27l "check setstripe permissions (should return error)"
1802
1803 test_27m() {
1804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1805
1806         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1807                 skip_env "multiple clients -- skipping"
1808
1809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1810                    head -n1)
1811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1813         fi
1814         stack_trap simple_cleanup_common
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1817         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1818                 error "dd should fill OST0"
1819         i=2
1820         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1821                 i=$((i + 1))
1822                 [ $i -gt 256 ] && break
1823         done
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it"
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it" || true
1834 }
1835 run_test 27m "create file while OST0 was full"
1836
1837 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1838 # if the OST isn't full anymore.
1839 reset_enospc() {
1840         local ostidx=${1:-""}
1841         local delay
1842         local ready
1843         local get_prealloc
1844
1845         local list=$(comma_list $(osts_nodes))
1846         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1847
1848         do_nodes $list lctl set_param fail_loc=0
1849         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1850         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1851                 awk '{print $1 * 2;exit;}')
1852         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1853                         grep -v \"^0$\""
1854         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1855 }
1856
1857 test_27n() {
1858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1860         remote_mds_nodsh && skip "remote MDS with nodsh"
1861         remote_ost_nodsh && skip "remote OST with nodsh"
1862
1863         reset_enospc
1864         rm -f $DIR/$tdir/$tfile
1865         exhaust_precreations 0 0x80000215
1866         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1867         touch $DIR/$tdir/$tfile || error "touch failed"
1868         $LFS getstripe $DIR/$tdir/$tfile
1869         reset_enospc
1870 }
1871 run_test 27n "create file with some full OSTs"
1872
1873 test_27o() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881         exhaust_all_precreations 0x215
1882
1883         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1884
1885         reset_enospc
1886         rm -rf $DIR/$tdir/*
1887 }
1888 run_test 27o "create file with all full OSTs (should error)"
1889
1890 function create_and_checktime() {
1891         local fname=$1
1892         local loops=$2
1893         local i
1894
1895         for ((i=0; i < $loops; i++)); do
1896                 local start=$SECONDS
1897                 multiop $fname-$i Oc
1898                 ((SECONDS-start < TIMEOUT)) ||
1899                         error "creation took " $((SECONDS-$start)) && return 1
1900         done
1901 }
1902
1903 test_27oo() {
1904         local mdts=$(comma_list $(mdts_nodes))
1905
1906         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1907                 skip "Need MDS version at least 2.13.57"
1908
1909         local f0=$DIR/${tfile}-0
1910         local f1=$DIR/${tfile}-1
1911
1912         wait_delete_completed
1913
1914         # refill precreated objects
1915         $LFS setstripe -i0 -c1 $f0
1916
1917         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1918         # force QoS allocation policy
1919         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1920         stack_trap "do_nodes $mdts $LCTL set_param \
1921                 lov.*.qos_threshold_rr=$saved" EXIT
1922         sleep_maxage
1923
1924         # one OST is unavailable, but still have few objects preallocated
1925         stop ost1
1926         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1927                 rm -rf $f1 $DIR/$tdir*" EXIT
1928
1929         for ((i=0; i < 7; i++)); do
1930                 mkdir $DIR/$tdir$i || error "can't create dir"
1931                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1932                         error "can't set striping"
1933         done
1934         for ((i=0; i < 7; i++)); do
1935                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1936         done
1937         wait
1938 }
1939 run_test 27oo "don't let few threads to reserve too many objects"
1940
1941 test_27p() {
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         reset_enospc
1948         rm -f $DIR/$tdir/$tfile
1949         test_mkdir $DIR/$tdir
1950
1951         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1952         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1953         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1954
1955         exhaust_precreations 0 0x80000215
1956         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1957         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1958         $LFS getstripe $DIR/$tdir/$tfile
1959
1960         reset_enospc
1961 }
1962 run_test 27p "append to a truncated file with some full OSTs"
1963
1964 test_27q() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972
1973         mkdir_on_mdt0 $DIR/$tdir
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1976                 error "truncate $DIR/$tdir/$tfile failed"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1978
1979         exhaust_all_precreations 0x215
1980
1981         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1982         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1983
1984         reset_enospc
1985 }
1986 run_test 27q "append to truncated file with all OSTs full (should error)"
1987
1988 test_27r() {
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         reset_enospc
1995         rm -f $DIR/$tdir/$tfile
1996         exhaust_precreations 0 0x80000215
1997
1998         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1999
2000         reset_enospc
2001 }
2002 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2003
2004 test_27s() { # bug 10725
2005         test_mkdir $DIR/$tdir
2006         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2007         local stripe_count=0
2008         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2009         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2010                 error "stripe width >= 2^32 succeeded" || true
2011
2012 }
2013 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2014
2015 test_27t() { # bug 10864
2016         WDIR=$(pwd)
2017         WLFS=$(which lfs)
2018         cd $DIR
2019         touch $tfile
2020         $WLFS getstripe $tfile
2021         cd $WDIR
2022 }
2023 run_test 27t "check that utils parse path correctly"
2024
2025 test_27u() { # bug 4900
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028
2029         local index
2030         local list=$(comma_list $(mdts_nodes))
2031
2032 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2033         do_nodes $list $LCTL set_param fail_loc=0x139
2034         test_mkdir -p $DIR/$tdir
2035         stack_trap "simple_cleanup_common 1000"
2036         createmany -o $DIR/$tdir/$tfile 1000
2037         do_nodes $list $LCTL set_param fail_loc=0
2038
2039         TLOG=$TMP/$tfile.getstripe
2040         $LFS getstripe $DIR/$tdir > $TLOG
2041         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2042         [[ $OBJS -gt 0 ]] &&
2043                 error "$OBJS objects created on OST-0. See $TLOG" ||
2044                 rm -f $TLOG
2045 }
2046 run_test 27u "skip object creation on OSC w/o objects"
2047
2048 test_27v() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2051         remote_mds_nodsh && skip "remote MDS with nodsh"
2052         remote_ost_nodsh && skip "remote OST with nodsh"
2053
2054         exhaust_all_precreations 0x215
2055         reset_enospc
2056
2057         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2058
2059         touch $DIR/$tdir/$tfile
2060         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2061         # all except ost1
2062         for (( i=1; i < OSTCOUNT; i++ )); do
2063                 do_facet ost$i lctl set_param fail_loc=0x705
2064         done
2065         local START=`date +%s`
2066         createmany -o $DIR/$tdir/$tfile 32
2067
2068         local FINISH=`date +%s`
2069         local TIMEOUT=`lctl get_param -n timeout`
2070         local PROCESS=$((FINISH - START))
2071         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2072                error "$FINISH - $START >= $TIMEOUT / 2"
2073         sleep $((TIMEOUT / 2 - PROCESS))
2074         reset_enospc
2075 }
2076 run_test 27v "skip object creation on slow OST"
2077
2078 test_27w() { # bug 10997
2079         test_mkdir $DIR/$tdir
2080         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2081         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2082                 error "stripe size $size != 65536" || true
2083         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2084                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2085 }
2086 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2087
2088 test_27wa() {
2089         [[ $OSTCOUNT -lt 2 ]] &&
2090                 skip_env "skipping multiple stripe count/offset test"
2091
2092         test_mkdir $DIR/$tdir
2093         for i in $(seq 1 $OSTCOUNT); do
2094                 offset=$((i - 1))
2095                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2096                         error "setstripe -c $i -i $offset failed"
2097                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2098                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2099                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2100                 [ $index -ne $offset ] &&
2101                         error "stripe offset $index != $offset" || true
2102         done
2103 }
2104 run_test 27wa "check $LFS setstripe -c -i options"
2105
2106 test_27x() {
2107         remote_ost_nodsh && skip "remote OST with nodsh"
2108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2110
2111         OFFSET=$(($OSTCOUNT - 1))
2112         OSTIDX=0
2113         local OST=$(ostname_from_index $OSTIDX)
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2117         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2118         sleep_maxage
2119         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2120         for i in $(seq 0 $OFFSET); do
2121                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2122                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2123                 error "OST0 was degraded but new created file still use it"
2124         done
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2126 }
2127 run_test 27x "create files while OST0 is degraded"
2128
2129 test_27y() {
2130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2131         remote_mds_nodsh && skip "remote MDS with nodsh"
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2134
2135         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2136         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2137                 osp.$mdtosc.prealloc_last_id)
2138         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_next_id)
2140         local fcount=$((last_id - next_id))
2141         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2142         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2143
2144         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2145                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2146         local OST_DEACTIVE_IDX=-1
2147         local OSC
2148         local OSTIDX
2149         local OST
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2155                         OST_DEACTIVE_IDX=$OSTIDX
2156                 fi
2157                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2158                         echo $OSC "is Deactivated:"
2159                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2160                 fi
2161         done
2162
2163         OSTIDX=$(index_from_ostuuid $OST)
2164         test_mkdir $DIR/$tdir
2165         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2166
2167         for OSC in $MDS_OSCS; do
2168                 OST=$(osc_to_ost $OSC)
2169                 OSTIDX=$(index_from_ostuuid $OST)
2170                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2171                         echo $OST "is degraded:"
2172                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2173                                                 obdfilter.$OST.degraded=1
2174                 fi
2175         done
2176
2177         sleep_maxage
2178         createmany -o $DIR/$tdir/$tfile $fcount
2179
2180         for OSC in $MDS_OSCS; do
2181                 OST=$(osc_to_ost $OSC)
2182                 OSTIDX=$(index_from_ostuuid $OST)
2183                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2184                         echo $OST "is recovered from degraded:"
2185                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2186                                                 obdfilter.$OST.degraded=0
2187                 else
2188                         do_facet $SINGLEMDS lctl --device %$OSC activate
2189                 fi
2190         done
2191
2192         # all osp devices get activated, hence -1 stripe count restored
2193         local stripe_count=0
2194
2195         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2196         # devices get activated.
2197         sleep_maxage
2198         $LFS setstripe -c -1 $DIR/$tfile
2199         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2200         rm -f $DIR/$tfile
2201         [ $stripe_count -ne $OSTCOUNT ] &&
2202                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2203         return 0
2204 }
2205 run_test 27y "create files while OST0 is degraded and the rest inactive"
2206
2207 check_seq_oid()
2208 {
2209         log "check file $1"
2210
2211         lmm_count=$($LFS getstripe -c $1)
2212         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2213         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2214
2215         local old_ifs="$IFS"
2216         IFS=$'[:]'
2217         fid=($($LFS path2fid $1))
2218         IFS="$old_ifs"
2219
2220         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2221         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2222
2223         # compare lmm_seq and lu_fid->f_seq
2224         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2225         # compare lmm_object_id and lu_fid->oid
2226         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2227
2228         # check the trusted.fid attribute of the OST objects of the file
2229         local have_obdidx=false
2230         local stripe_nr=0
2231         $LFS getstripe $1 | while read obdidx oid hex seq; do
2232                 # skip lines up to and including "obdidx"
2233                 [ -z "$obdidx" ] && break
2234                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2235                 $have_obdidx || continue
2236
2237                 local ost=$((obdidx + 1))
2238                 local dev=$(ostdevname $ost)
2239                 local oid_hex
2240
2241                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2242
2243                 seq=$(echo $seq | sed -e "s/^0x//g")
2244                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2245                         oid_hex=$(echo $oid)
2246                 else
2247                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2248                 fi
2249                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2250
2251                 local ff=""
2252                 #
2253                 # Don't unmount/remount the OSTs if we don't need to do that.
2254                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2255                 # update too, until that use mount/ll_decode_filter_fid/mount.
2256                 # Re-enable when debugfs will understand new filter_fid.
2257                 #
2258                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2259                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2260                                 $dev 2>/dev/null" | grep "parent=")
2261                 fi
2262                 if [ -z "$ff" ]; then
2263                         stop ost$ost
2264                         mount_fstype ost$ost
2265                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2266                                 $(facet_mntpt ost$ost)/$obj_file)
2267                         unmount_fstype ost$ost
2268                         start ost$ost $dev $OST_MOUNT_OPTS
2269                         clients_up
2270                 fi
2271
2272                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2273
2274                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2275
2276                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2277                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2278                 #
2279                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2280                 #       stripe_size=1048576 component_id=1 component_start=0 \
2281                 #       component_end=33554432
2282                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2283                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2284                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2285                 local ff_pstripe
2286                 if grep -q 'stripe=' <<<$ff; then
2287                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2288                 else
2289                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2290                         # into f_ver in this case.  See comment on ff_parent.
2291                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2292                 fi
2293
2294                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2295                 [ $ff_pseq = $lmm_seq ] ||
2296                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2297                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2298                 [ $ff_poid = $lmm_oid ] ||
2299                         error "FF parent OID $ff_poid != $lmm_oid"
2300                 (($ff_pstripe == $stripe_nr)) ||
2301                         error "FF stripe $ff_pstripe != $stripe_nr"
2302
2303                 stripe_nr=$((stripe_nr + 1))
2304                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2305                         continue
2306                 if grep -q 'stripe_count=' <<<$ff; then
2307                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2308                                             -e 's/ .*//' <<<$ff)
2309                         [ $lmm_count = $ff_scnt ] ||
2310                                 error "FF stripe count $lmm_count != $ff_scnt"
2311                 fi
2312         done
2313 }
2314
2315 test_27z() {
2316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2317         remote_ost_nodsh && skip "remote OST with nodsh"
2318
2319         test_mkdir $DIR/$tdir
2320         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2321                 { error "setstripe -c -1 failed"; return 1; }
2322         # We need to send a write to every object to get parent FID info set.
2323         # This _should_ also work for setattr, but does not currently.
2324         # touch $DIR/$tdir/$tfile-1 ||
2325         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2326                 { error "dd $tfile-1 failed"; return 2; }
2327         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2328                 { error "setstripe -c -1 failed"; return 3; }
2329         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2330                 { error "dd $tfile-2 failed"; return 4; }
2331
2332         # make sure write RPCs have been sent to OSTs
2333         sync; sleep 5; sync
2334
2335         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2336         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2337 }
2338 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2339
2340 test_27A() { # b=19102
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342
2343         save_layout_restore_at_exit $MOUNT
2344         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2345         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2346                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2347         local default_size=$($LFS getstripe -S $MOUNT)
2348         local default_offset=$($LFS getstripe -i $MOUNT)
2349         local dsize=$(do_facet $SINGLEMDS \
2350                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2351         [ $default_size -eq $dsize ] ||
2352                 error "stripe size $default_size != $dsize"
2353         [ $default_offset -eq -1 ] ||
2354                 error "stripe offset $default_offset != -1"
2355 }
2356 run_test 27A "check filesystem-wide default LOV EA values"
2357
2358 test_27B() { # LU-2523
2359         test_mkdir $DIR/$tdir
2360         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2361         touch $DIR/$tdir/f0
2362         # open f1 with O_LOV_DELAY_CREATE
2363         # rename f0 onto f1
2364         # call setstripe ioctl on open file descriptor for f1
2365         # close
2366         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2367                 $DIR/$tdir/f0
2368
2369         rm -f $DIR/$tdir/f1
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # unlink f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2375
2376         # Allow multiop to fail in imitation of NFS's busted semantics.
2377         true
2378 }
2379 run_test 27B "call setstripe on open unlinked file/rename victim"
2380
2381 # 27C family tests full striping and overstriping
2382 test_27Ca() { #LU-2871
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384
2385         declare -a ost_idx
2386         local index
2387         local found
2388         local i
2389         local j
2390
2391         test_mkdir $DIR/$tdir
2392         cd $DIR/$tdir
2393         for i in $(seq 0 $((OSTCOUNT - 1))); do
2394                 # set stripe across all OSTs starting from OST$i
2395                 $LFS setstripe -i $i -c -1 $tfile$i
2396                 # get striping information
2397                 ost_idx=($($LFS getstripe $tfile$i |
2398                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2399                 echo ${ost_idx[@]}
2400
2401                 # check the layout
2402                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2403                         error "${#ost_idx[@]} != $OSTCOUNT"
2404
2405                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2406                         found=0
2407                         for j in $(echo ${ost_idx[@]}); do
2408                                 if [ $index -eq $j ]; then
2409                                         found=1
2410                                         break
2411                                 fi
2412                         done
2413                         [ $found = 1 ] ||
2414                                 error "Can not find $index in ${ost_idx[@]}"
2415                 done
2416         done
2417 }
2418 run_test 27Ca "check full striping across all OSTs"
2419
2420 test_27Cb() {
2421         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2422                 skip "server does not support overstriping"
2423         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2424                 skip_env "too many osts, skipping"
2425
2426         test_mkdir -p $DIR/$tdir
2427         local setcount=$(($OSTCOUNT * 2))
2428         [ $setcount -lt 160 ] || large_xattr_enabled ||
2429                 skip_env "ea_inode feature disabled"
2430
2431         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2432                 error "setstripe failed"
2433
2434         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2435         [ $count -eq $setcount ] ||
2436                 error "stripe count $count, should be $setcount"
2437
2438         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2439                 error "overstriped should be set in pattern"
2440
2441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2442                 error "dd failed"
2443 }
2444 run_test 27Cb "more stripes than OSTs with -C"
2445
2446 test_27Cc() {
2447         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2448                 skip "server does not support overstriping"
2449         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT - 1))
2453
2454         [ $setcount -lt 160 ] || large_xattr_enabled ||
2455                 skip_env "ea_inode feature disabled"
2456
2457         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2465                 error "overstriped should not be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469 }
2470 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2471
2472 test_27Cd() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2476         large_xattr_enabled || skip_env "ea_inode feature disabled"
2477
2478         test_mkdir -p $DIR/$tdir
2479         local setcount=$LOV_MAX_STRIPE_COUNT
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493
2494         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2495 }
2496 run_test 27Cd "test maximum stripe count"
2497
2498 test_27Ce() {
2499         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2500                 skip "server does not support overstriping"
2501         test_mkdir -p $DIR/$tdir
2502
2503         pool_add $TESTNAME || error "Pool creation failed"
2504         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2505
2506         local setcount=8
2507
2508         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2509                 error "setstripe failed"
2510
2511         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2512         [ $count -eq $setcount ] ||
2513                 error "stripe count $count, should be $setcount"
2514
2515         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2516                 error "overstriped should be set in pattern"
2517
2518         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2519                 error "dd failed"
2520
2521         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2522 }
2523 run_test 27Ce "test pool with overstriping"
2524
2525 test_27Cf() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip_env "too many osts, skipping"
2530
2531         test_mkdir -p $DIR/$tdir
2532
2533         local setcount=$(($OSTCOUNT * 2))
2534         [ $setcount -lt 160 ] || large_xattr_enabled ||
2535                 skip_env "ea_inode feature disabled"
2536
2537         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2538                 error "setstripe failed"
2539
2540         echo 1 > $DIR/$tdir/$tfile
2541
2542         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2543         [ $count -eq $setcount ] ||
2544                 error "stripe count $count, should be $setcount"
2545
2546         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2547                 error "overstriped should be set in pattern"
2548
2549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2550                 error "dd failed"
2551
2552         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2553 }
2554 run_test 27Cf "test default inheritance with overstriping"
2555
2556 test_27D() {
2557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2559         remote_mds_nodsh && skip "remote MDS with nodsh"
2560
2561         local POOL=${POOL:-testpool}
2562         local first_ost=0
2563         local last_ost=$(($OSTCOUNT - 1))
2564         local ost_step=1
2565         local ost_list=$(seq $first_ost $ost_step $last_ost)
2566         local ost_range="$first_ost $last_ost $ost_step"
2567
2568         test_mkdir $DIR/$tdir
2569         pool_add $POOL || error "pool_add failed"
2570         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2571
2572         local skip27D
2573         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2574                 skip27D+="-s 29"
2575         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2576                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2577                         skip27D+=" -s 30,31"
2578         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2579           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2580                 skip27D+=" -s 32,33"
2581         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2582                 skip27D+=" -s 34"
2583         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2584                 error "llapi_layout_test failed"
2585
2586         destroy_test_pools || error "destroy test pools failed"
2587 }
2588 run_test 27D "validate llapi_layout API"
2589
2590 # Verify that default_easize is increased from its initial value after
2591 # accessing a widely striped file.
2592 test_27E() {
2593         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2594         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2595                 skip "client does not have LU-3338 fix"
2596
2597         # 72 bytes is the minimum space required to store striping
2598         # information for a file striped across one OST:
2599         # (sizeof(struct lov_user_md_v3) +
2600         #  sizeof(struct lov_user_ost_data_v1))
2601         local min_easize=72
2602         $LCTL set_param -n llite.*.default_easize $min_easize ||
2603                 error "lctl set_param failed"
2604         local easize=$($LCTL get_param -n llite.*.default_easize)
2605
2606         [ $easize -eq $min_easize ] ||
2607                 error "failed to set default_easize"
2608
2609         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2610                 error "setstripe failed"
2611         # In order to ensure stat() call actually talks to MDS we need to
2612         # do something drastic to this file to shake off all lock, e.g.
2613         # rename it (kills lookup lock forcing cache cleaning)
2614         mv $DIR/$tfile $DIR/${tfile}-1
2615         ls -l $DIR/${tfile}-1
2616         rm $DIR/${tfile}-1
2617
2618         easize=$($LCTL get_param -n llite.*.default_easize)
2619
2620         [ $easize -gt $min_easize ] ||
2621                 error "default_easize not updated"
2622 }
2623 run_test 27E "check that default extended attribute size properly increases"
2624
2625 test_27F() { # LU-5346/LU-7975
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2629                 skip "Need MDS version at least 2.8.51"
2630         remote_ost_nodsh && skip "remote OST with nodsh"
2631
2632         test_mkdir $DIR/$tdir
2633         rm -f $DIR/$tdir/f0
2634         $LFS setstripe -c 2 $DIR/$tdir
2635
2636         # stop all OSTs to reproduce situation for LU-7975 ticket
2637         for num in $(seq $OSTCOUNT); do
2638                 stop ost$num
2639         done
2640
2641         # open/create f0 with O_LOV_DELAY_CREATE
2642         # truncate f0 to a non-0 size
2643         # close
2644         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2645
2646         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2647         # open/write it again to force delayed layout creation
2648         cat /etc/hosts > $DIR/$tdir/f0 &
2649         catpid=$!
2650
2651         # restart OSTs
2652         for num in $(seq $OSTCOUNT); do
2653                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2654                         error "ost$num failed to start"
2655         done
2656
2657         wait $catpid || error "cat failed"
2658
2659         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2660         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2661                 error "wrong stripecount"
2662
2663 }
2664 run_test 27F "Client resend delayed layout creation with non-zero size"
2665
2666 test_27G() { #LU-10629
2667         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2668                 skip "Need MDS version at least 2.11.51"
2669         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2670         remote_mds_nodsh && skip "remote MDS with nodsh"
2671         local POOL=${POOL:-testpool}
2672         local ostrange="0 0 1"
2673
2674         test_mkdir $DIR/$tdir
2675         touch $DIR/$tdir/$tfile.nopool
2676         pool_add $POOL || error "pool_add failed"
2677         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2678         $LFS setstripe -p $POOL $DIR/$tdir
2679
2680         local pool=$($LFS getstripe -p $DIR/$tdir)
2681
2682         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2683         touch $DIR/$tdir/$tfile.default
2684         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2685         $LFS find $DIR/$tdir -type f --pool $POOL
2686         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2687         [[ "$found" == "2" ]] ||
2688                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2689
2690         $LFS setstripe -d $DIR/$tdir
2691
2692         pool=$($LFS getstripe -p -d $DIR/$tdir)
2693
2694         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2695 }
2696 run_test 27G "Clear OST pool from stripe"
2697
2698 test_27H() {
2699         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2700                 skip "Need MDS version newer than 2.11.54"
2701         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2704         touch $DIR/$tdir/$tfile
2705         $LFS getstripe -c $DIR/$tdir/$tfile
2706         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2707                 error "two-stripe file doesn't have two stripes"
2708
2709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2710         $LFS getstripe -y $DIR/$tdir/$tfile
2711         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2712              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2713                 error "expected l_ost_idx: [02]$ not matched"
2714
2715         # make sure ost list has been cleared
2716         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2719         touch $DIR/$tdir/f3
2720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2721 }
2722 run_test 27H "Set specific OSTs stripe"
2723
2724 test_27I() {
2725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2727         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2728                 skip "Need MDS version newer than 2.12.52"
2729         local pool=$TESTNAME
2730         local ostrange="1 1 1"
2731
2732         save_layout_restore_at_exit $MOUNT
2733         $LFS setstripe -c 2 -i 0 $MOUNT
2734         pool_add $pool || error "pool_add failed"
2735         pool_add_targets $pool $ostrange ||
2736                 error "pool_add_targets failed"
2737         test_mkdir $DIR/$tdir
2738         $LFS setstripe -p $pool $DIR/$tdir
2739         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2740         $LFS getstripe $DIR/$tdir/$tfile
2741 }
2742 run_test 27I "check that root dir striping does not break parent dir one"
2743
2744 test_27J() {
2745         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2746                 skip "Need MDS version newer than 2.12.51"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign file (raw way)
2753         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2754                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2755
2756         ! $LFS setstripe --foreign --flags foo \
2757                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2758                         error "creating $tfile with '--flags foo' should fail"
2759
2760         ! $LFS setstripe --foreign --flags 0xffffffff \
2761                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2762                         error "creating $tfile w/ 0xffffffff flags should fail"
2763
2764         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2765                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2766
2767         # verify foreign file (raw way)
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2771         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_size: 73" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_type: 1" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_flags: 0x0000DA08" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2782         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_value: 0x" |
2784                 sed -e 's/lov_foreign_value: 0x//')
2785         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2786         [[ $lov = ${lov2// /} ]] ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2788
2789         # create foreign file (lfs + API)
2790         $LFS setstripe --foreign=none --flags 0xda08 \
2791                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2792                 error "$DIR/$tdir/${tfile}2: create failed"
2793
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2795                 grep "lfm_magic:.*0x0BD70BD0" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2797         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2798         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_flags:.*0x0000DA08" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2805         $LFS getstripe $DIR/$tdir/${tfile}2 |
2806                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2808
2809         # modify striping should fail
2810         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2811                 error "$DIR/$tdir/$tfile: setstripe should fail"
2812         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2814
2815         # R/W should fail
2816         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2817         cat $DIR/$tdir/${tfile}2 &&
2818                 error "$DIR/$tdir/${tfile}2: read should fail"
2819         cat /etc/passwd > $DIR/$tdir/$tfile &&
2820                 error "$DIR/$tdir/$tfile: write should fail"
2821         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2822                 error "$DIR/$tdir/${tfile}2: write should fail"
2823
2824         # chmod should work
2825         chmod 222 $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chmod failed"
2827         chmod 222 $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chmod failed"
2829
2830         # chown should work
2831         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chown failed"
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chown failed"
2835
2836         # rename should work
2837         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2839         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2841
2842         #remove foreign file
2843         rm $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2845         rm $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2847 }
2848 run_test 27J "basic ops on file with foreign LOV"
2849
2850 test_27K() {
2851         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2852                 skip "Need MDS version newer than 2.12.49"
2853
2854         test_mkdir $DIR/$tdir
2855         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2856         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2857
2858         # create foreign dir (raw way)
2859         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2860                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2861
2862         ! $LFS setdirstripe --foreign --flags foo \
2863                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2864                         error "creating $tdir with '--flags foo' should fail"
2865
2866         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2867                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2868                         error "creating $tdir w/ 0xffffffff flags should fail"
2869
2870         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2871                 error "create_foreign_dir FAILED"
2872
2873         # verify foreign dir (raw way)
2874         parse_foreign_dir -d $DIR/$tdir/$tdir |
2875                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2876                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2877         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir |
2882                 grep "lmv_foreign_flags: 55813$" ||
2883                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2884         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2885                 grep "lmv_foreign_value: 0x" |
2886                 sed 's/lmv_foreign_value: 0x//')
2887         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2888                 sed 's/ //g')
2889         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2890
2891         # create foreign dir (lfs + API)
2892         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2893                 $DIR/$tdir/${tdir}2 ||
2894                 error "$DIR/$tdir/${tdir}2: create failed"
2895
2896         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2897                 grep "lfm_magic:.*0x0CD50CD0" ||
2898                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2899         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2900         # - sizeof(lfm_type) - sizeof(lfm_flags)
2901         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2902                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_flags:.*0x0000DA05" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2908         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2909                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2911
2912         # file create in dir should fail
2913         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2914         touch $DIR/$tdir/${tdir}2/$tfile &&
2915                 error "$DIR/${tdir}2: file create should fail"
2916
2917         # chmod should work
2918         chmod 777 $DIR/$tdir/$tdir ||
2919                 error "$DIR/$tdir: chmod failed"
2920         chmod 777 $DIR/$tdir/${tdir}2 ||
2921                 error "$DIR/${tdir}2: chmod failed"
2922
2923         # chown should work
2924         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2925                 error "$DIR/$tdir: chown failed"
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2927                 error "$DIR/${tdir}2: chown failed"
2928
2929         # rename should work
2930         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2931                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2932         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2933                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2934
2935         #remove foreign dir
2936         rmdir $DIR/$tdir/${tdir}.new ||
2937                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2938         rmdir $DIR/$tdir/${tdir}2.new ||
2939                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2940 }
2941 run_test 27K "basic ops on dir with foreign LMV"
2942
2943 test_27L() {
2944         remote_mds_nodsh && skip "remote MDS with nodsh"
2945
2946         local POOL=${POOL:-$TESTNAME}
2947
2948         pool_add $POOL || error "pool_add failed"
2949
2950         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2951                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2952                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2953 }
2954 run_test 27L "lfs pool_list gives correct pool name"
2955
2956 test_27M() {
2957         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2958                 skip "Need MDS version >= than 2.12.57"
2959         remote_mds_nodsh && skip "remote MDS with nodsh"
2960         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2961
2962         test_mkdir $DIR/$tdir
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967
2968         # if we run against a 2.12 server which lacks overstring support
2969         # then the connect_flag will not report overstriping, even if client
2970         # is 2.14+
2971         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2972                 stripe_opt="-C $setcount"
2973         elif (( $OSTCOUNT >= $setcount )); then
2974                 stripe_opt="-c $setcount"
2975         else
2976                 skip "server does not support overstriping"
2977         fi
2978         $LFS setstripe $stripe_opt $DIR/$tdir
2979
2980         echo 1 > $DIR/$tdir/${tfile}.1
2981         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2982         [ $count -eq $setcount ] ||
2983                 error "(1) stripe count $count, should be $setcount"
2984
2985         # Capture existing append_stripe_count setting for restore
2986         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2987         local mdts=$(comma_list $(mdts_nodes))
2988         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2989
2990         local appendcount=$orig_count
2991         echo 1 >> $DIR/$tdir/${tfile}.2_append
2992         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2993         [ $count -eq $appendcount ] ||
2994                 error "(2)stripe count $count, should be $appendcount for append"
2995
2996         # Disable O_APPEND striping, verify it works
2997         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2998
2999         # Should now get the default striping, which is 4
3000         setcount=4
3001         echo 1 >> $DIR/$tdir/${tfile}.3_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3003         [ $count -eq $setcount ] ||
3004                 error "(3) stripe count $count, should be $setcount"
3005
3006         # Try changing the stripe count for append files
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3008
3009         # Append striping is now 2 (directory default is still 4)
3010         appendcount=2
3011         echo 1 >> $DIR/$tdir/${tfile}.4_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3013         [ $count -eq $appendcount ] ||
3014                 error "(4) stripe count $count, should be $appendcount for append"
3015
3016         # Test append stripe count of -1
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3018         appendcount=$OSTCOUNT
3019         echo 1 >> $DIR/$tdir/${tfile}.5
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3021         [ $count -eq $appendcount ] ||
3022                 error "(5) stripe count $count, should be $appendcount for append"
3023
3024         # Set append striping back to default of 1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3026
3027         # Try a new default striping, PFL + DOM
3028         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3029
3030         # Create normal DOM file, DOM returns stripe count == 0
3031         setcount=0
3032         touch $DIR/$tdir/${tfile}.6
3033         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3034         [ $count -eq $setcount ] ||
3035                 error "(6) stripe count $count, should be $setcount"
3036
3037         # Show
3038         appendcount=1
3039         echo 1 >> $DIR/$tdir/${tfile}.7_append
3040         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3041         [ $count -eq $appendcount ] ||
3042                 error "(7) stripe count $count, should be $appendcount for append"
3043
3044         # Clean up DOM layout
3045         $LFS setstripe -d $DIR/$tdir
3046
3047         save_layout_restore_at_exit $MOUNT
3048         # Now test that append striping works when layout is from root
3049         $LFS setstripe -c 2 $MOUNT
3050         # Make a special directory for this
3051         mkdir $DIR/${tdir}/${tdir}.2
3052
3053         # Verify for normal file
3054         setcount=2
3055         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3056         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3057         [ $count -eq $setcount ] ||
3058                 error "(8) stripe count $count, should be $setcount"
3059
3060         appendcount=1
3061         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3062         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3063         [ $count -eq $appendcount ] ||
3064                 error "(9) stripe count $count, should be $appendcount for append"
3065
3066         # Now test O_APPEND striping with pools
3067         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3068         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3069
3070         # Create the pool
3071         pool_add $TESTNAME || error "pool creation failed"
3072         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3238                 grep "lfm_magic:.*0x0CD50CD0" ||
3239                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3240         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3243                 grep "lfm_flags:.*0x0000DA05" ||
3244                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3245         $LFS getdirstripe $DIR/$tdir/${tdir} |
3246                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3248
3249         # file create in dir should fail
3250         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3251         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3252
3253         # rename should succeed
3254         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3255                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3256
3257         #remove foreign_symlink dir should fail
3258         rmdir $DIR/$tdir/${tdir}.new &&
3259                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3260
3261         #test fake symlink
3262         mkdir -p /tmp/${uuid1}/${uuid2} ||
3263                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3264         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3265                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3266         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3267         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3268                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3269         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3270                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3271
3272         #check that getstripe fails now that foreign_symlink enabled
3273         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3274                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3275
3276         # file create in dir should work now
3277         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3278                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3279         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3281         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3282                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3283
3284         # chmod should still succeed
3285         chmod 755 $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3287
3288         # chown should still succeed
3289         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3290                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3291
3292         # rename should still succeed
3293         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3294                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3295
3296         #remove foreign_symlink dir should still fail
3297         rmdir $DIR/$tdir/${tdir} &&
3298                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3299
3300         #use special ioctl() to unlink foreign_symlink file
3301         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3302                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3303
3304         #created file should still exist
3305         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3306                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3307         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3309 }
3310 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3311
3312 test_27Q() {
3313         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3314         stack_trap "rm -f $TMP/$tfile*"
3315
3316         test_mkdir $DIR/$tdir-1
3317         test_mkdir $DIR/$tdir-2
3318
3319         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3320         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3321
3322         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3323         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3324
3325         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3326         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3327
3328         # Create some bad symlinks and ensure that we don't loop
3329         # forever or something. These should return ELOOP (40) and
3330         # ENOENT (2) but I don't want to test for that because there's
3331         # always some weirdo architecture that needs to ruin
3332         # everything by defining these error numbers differently.
3333
3334         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3335         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3336
3337         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3338         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3339
3340         return 0
3341 }
3342 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3343
3344 test_27R() {
3345         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3346                 skip "need MDS 2.14.55 or later"
3347         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3348
3349         local testdir="$DIR/$tdir"
3350         test_mkdir -p $testdir
3351         stack_trap "rm -rf $testdir"
3352         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3353
3354         local f1="$testdir/f1"
3355         touch $f1 || error "failed to touch $f1"
3356         local count=$($LFS getstripe -c $f1)
3357         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3358
3359         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3360         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3361
3362         local maxcount=$(($OSTCOUNT - 1))
3363         local mdts=$(comma_list $(mdts_nodes))
3364         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3365         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3366
3367         local f2="$testdir/f2"
3368         touch $f2 || error "failed to touch $f2"
3369         local count=$($LFS getstripe -c $f2)
3370         (( $count == $maxcount )) || error "wrong stripe count"
3371 }
3372 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3373
3374 test_27S() {
3375         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3376                 skip "Need MDS version at least 2.14.54"
3377         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3378                 skip "needs different host for mdt1 ost1"
3379
3380         local count=$(precreated_ost_obj_count 0 0)
3381
3382         echo "precreate count $count"
3383         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3385         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3386         do_facet mds1 $LCTL set_param fail_loc=0x2109
3387         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3388         do_facet ost1 $LCTL set_param fail_loc=0x252
3389         createmany -o $DIR/$tdir/f $count &
3390         pid=$!
3391         echo "precreate count $(precreated_ost_obj_count 0 0)"
3392         do_facet mds1 $LCTL set_param fail_loc=0
3393         do_facet ost1 $LCTL set_param fail_loc=0
3394         wait $pid || error "createmany failed"
3395         echo "precreate count $(precreated_ost_obj_count 0 0)"
3396 }
3397 run_test 27S "don't deactivate OSP on network issue"
3398
3399 # createtest also checks that device nodes are created and
3400 # then visible correctly (#2091)
3401 test_28() { # bug 2091
3402         test_mkdir $DIR/d28
3403         $CREATETEST $DIR/d28/ct || error "createtest failed"
3404 }
3405 run_test 28 "create/mknod/mkdir with bad file types ============"
3406
3407 test_29() {
3408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3409
3410         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3411                 disable_opencache
3412                 stack_trap "restore_opencache"
3413         }
3414
3415         sync; sleep 1; sync # flush out any dirty pages from previous tests
3416         cancel_lru_locks
3417         test_mkdir $DIR/d29
3418         touch $DIR/d29/foo
3419         log 'first d29'
3420         ls -l $DIR/d29
3421
3422         declare -i LOCKCOUNTORIG=0
3423         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3424                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3425         done
3426         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3427
3428         declare -i LOCKUNUSEDCOUNTORIG=0
3429         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3430                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3431         done
3432
3433         log 'second d29'
3434         ls -l $DIR/d29
3435         log 'done'
3436
3437         declare -i LOCKCOUNTCURRENT=0
3438         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3439                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3440         done
3441
3442         declare -i LOCKUNUSEDCOUNTCURRENT=0
3443         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3444                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3445         done
3446
3447         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3448                 $LCTL set_param -n ldlm.dump_namespaces ""
3449                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3450                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3451                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3452                 return 2
3453         fi
3454         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3455                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3456                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3457                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3458                 return 3
3459         fi
3460 }
3461 run_test 29 "IT_GETATTR regression  ============================"
3462
3463 test_30a() { # was test_30
3464         cp $(which ls) $DIR || cp /bin/ls $DIR
3465         $DIR/ls / || error "Can't execute binary from lustre"
3466         rm $DIR/ls
3467 }
3468 run_test 30a "execute binary from Lustre (execve) =============="
3469
3470 test_30b() {
3471         cp `which ls` $DIR || cp /bin/ls $DIR
3472         chmod go+rx $DIR/ls
3473         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3474         rm $DIR/ls
3475 }
3476 run_test 30b "execute binary from Lustre as non-root ==========="
3477
3478 test_30c() { # b=22376
3479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3480
3481         cp $(which ls) $DIR || cp /bin/ls $DIR
3482         chmod a-rw $DIR/ls
3483         cancel_lru_locks mdc
3484         cancel_lru_locks osc
3485         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3486         rm -f $DIR/ls
3487 }
3488 run_test 30c "execute binary from Lustre without read perms ===="
3489
3490 test_30d() {
3491         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3492
3493         for i in {1..10}; do
3494                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3495                 local PID=$!
3496                 sleep 1
3497                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3498                 wait $PID || error "executing dd from Lustre failed"
3499                 rm -f $DIR/$tfile
3500         done
3501
3502         rm -f $DIR/dd
3503 }
3504 run_test 30d "execute binary from Lustre while clear locks"
3505
3506 test_31a() {
3507         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3508         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3509 }
3510 run_test 31a "open-unlink file =================================="
3511
3512 test_31b() {
3513         touch $DIR/f31 || error "touch $DIR/f31 failed"
3514         ln $DIR/f31 $DIR/f31b || error "ln failed"
3515         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3516         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3517 }
3518 run_test 31b "unlink file with multiple links while open ======="
3519
3520 test_31c() {
3521         touch $DIR/f31 || error "touch $DIR/f31 failed"
3522         ln $DIR/f31 $DIR/f31c || error "ln failed"
3523         multiop_bg_pause $DIR/f31 O_uc ||
3524                 error "multiop_bg_pause for $DIR/f31 failed"
3525         MULTIPID=$!
3526         $MULTIOP $DIR/f31c Ouc
3527         kill -USR1 $MULTIPID
3528         wait $MULTIPID
3529 }
3530 run_test 31c "open-unlink file with multiple links ============="
3531
3532 test_31d() {
3533         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3534         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3535 }
3536 run_test 31d "remove of open directory ========================="
3537
3538 test_31e() { # bug 2904
3539         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3540 }
3541 run_test 31e "remove of open non-empty directory ==============="
3542
3543 test_31f() { # bug 4554
3544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3545
3546         set -vx
3547         test_mkdir $DIR/d31f
3548         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3549         cp /etc/hosts $DIR/d31f
3550         ls -l $DIR/d31f
3551         $LFS getstripe $DIR/d31f/hosts
3552         multiop_bg_pause $DIR/d31f D_c || return 1
3553         MULTIPID=$!
3554
3555         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3556         test_mkdir $DIR/d31f
3557         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3558         cp /etc/hosts $DIR/d31f
3559         ls -l $DIR/d31f
3560         $LFS getstripe $DIR/d31f/hosts
3561         multiop_bg_pause $DIR/d31f D_c || return 1
3562         MULTIPID2=$!
3563
3564         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3565         wait $MULTIPID || error "first opendir $MULTIPID failed"
3566
3567         sleep 6
3568
3569         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3570         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3571         set +vx
3572 }
3573 run_test 31f "remove of open directory with open-unlink file ==="
3574
3575 test_31g() {
3576         echo "-- cross directory link --"
3577         test_mkdir -c1 $DIR/${tdir}ga
3578         test_mkdir -c1 $DIR/${tdir}gb
3579         touch $DIR/${tdir}ga/f
3580         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3581         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3582         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3583         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3584         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3585 }
3586 run_test 31g "cross directory link==============="
3587
3588 test_31h() {
3589         echo "-- cross directory link --"
3590         test_mkdir -c1 $DIR/${tdir}
3591         test_mkdir -c1 $DIR/${tdir}/dir
3592         touch $DIR/${tdir}/f
3593         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3594         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3595         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3596         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3597         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3598 }
3599 run_test 31h "cross directory link under child==============="
3600
3601 test_31i() {
3602         echo "-- cross directory link --"
3603         test_mkdir -c1 $DIR/$tdir
3604         test_mkdir -c1 $DIR/$tdir/dir
3605         touch $DIR/$tdir/dir/f
3606         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3607         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3608         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3609         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3610         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3611 }
3612 run_test 31i "cross directory link under parent==============="
3613
3614 test_31j() {
3615         test_mkdir -c1 -p $DIR/$tdir
3616         test_mkdir -c1 -p $DIR/$tdir/dir1
3617         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3618         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3619         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3620         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3621         return 0
3622 }
3623 run_test 31j "link for directory==============="
3624
3625 test_31k() {
3626         test_mkdir -c1 -p $DIR/$tdir
3627         touch $DIR/$tdir/s
3628         touch $DIR/$tdir/exist
3629         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3630         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3631         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3632         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3633         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3634         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3635         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3636         return 0
3637 }
3638 run_test 31k "link to file: the same, non-existing, dir==============="
3639
3640 test_31m() {
3641         mkdir $DIR/d31m
3642         touch $DIR/d31m/s
3643         mkdir $DIR/d31m2
3644         touch $DIR/d31m2/exist
3645         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3646         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3647         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3648         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3649         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3650         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3651         return 0
3652 }
3653 run_test 31m "link to file: the same, non-existing, dir==============="
3654
3655 test_31n() {
3656         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3657         nlink=$(stat --format=%h $DIR/$tfile)
3658         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3659         local fd=$(free_fd)
3660         local cmd="exec $fd<$DIR/$tfile"
3661         eval $cmd
3662         cmd="exec $fd<&-"
3663         trap "eval $cmd" EXIT
3664         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3665         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3666         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3667         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3668         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3669         eval $cmd
3670 }
3671 run_test 31n "check link count of unlinked file"
3672
3673 link_one() {
3674         local tempfile=$(mktemp $1_XXXXXX)
3675         mlink $tempfile $1 2> /dev/null &&
3676                 echo "$BASHPID: link $tempfile to $1 succeeded"
3677         munlink $tempfile
3678 }
3679
3680 test_31o() { # LU-2901
3681         test_mkdir $DIR/$tdir
3682         for LOOP in $(seq 100); do
3683                 rm -f $DIR/$tdir/$tfile*
3684                 for THREAD in $(seq 8); do
3685                         link_one $DIR/$tdir/$tfile.$LOOP &
3686                 done
3687                 wait
3688                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3689                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3690                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3691                         break || true
3692         done
3693 }
3694 run_test 31o "duplicate hard links with same filename"
3695
3696 test_31p() {
3697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3698
3699         test_mkdir $DIR/$tdir
3700         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3701         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3702
3703         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3704                 error "open unlink test1 failed"
3705         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3706                 error "open unlink test2 failed"
3707
3708         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3709                 error "test1 still exists"
3710         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3711                 error "test2 still exists"
3712 }
3713 run_test 31p "remove of open striped directory"
3714
3715 test_31q() {
3716         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3717
3718         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3719         index=$($LFS getdirstripe -i $DIR/$tdir)
3720         [ $index -eq 3 ] || error "first stripe index $index != 3"
3721         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3722         [ $index -eq 1 ] || error "second stripe index $index != 1"
3723
3724         # when "-c <stripe_count>" is set, the number of MDTs specified after
3725         # "-i" should equal to the stripe count
3726         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3727 }
3728 run_test 31q "create striped directory on specific MDTs"
3729
3730 #LU-14949
3731 test_31r() {
3732         touch $DIR/$tfile.target
3733         touch $DIR/$tfile.source
3734
3735         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3736         $LCTL set_param fail_loc=0x1419 fail_val=3
3737         cat $DIR/$tfile.target &
3738         CATPID=$!
3739
3740         # Guarantee open is waiting before we get here
3741         sleep 1
3742         mv $DIR/$tfile.source $DIR/$tfile.target
3743
3744         wait $CATPID
3745         RC=$?
3746         if [[ $RC -ne 0 ]]; then
3747                 error "open with cat failed, rc=$RC"
3748         fi
3749 }
3750 run_test 31r "open-rename(replace) race"
3751
3752 cleanup_test32_mount() {
3753         local rc=0
3754         trap 0
3755         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3756         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3757         losetup -d $loopdev || true
3758         rm -rf $DIR/$tdir
3759         return $rc
3760 }
3761
3762 test_32a() {
3763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3764
3765         echo "== more mountpoints and symlinks ================="
3766         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3767         trap cleanup_test32_mount EXIT
3768         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3769         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3770                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3771         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3772                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3773         cleanup_test32_mount
3774 }
3775 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3776
3777 test_32b() {
3778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3779
3780         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3781         trap cleanup_test32_mount EXIT
3782         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3783         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3784                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3785         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3786                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3787         cleanup_test32_mount
3788 }
3789 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3790
3791 test_32c() {
3792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3793
3794         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3795         trap cleanup_test32_mount EXIT
3796         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3797         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3798                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3799         test_mkdir -p $DIR/$tdir/d2/test_dir
3800         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3801                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3802         cleanup_test32_mount
3803 }
3804 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3805
3806 test_32d() {
3807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3808
3809         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3810         trap cleanup_test32_mount EXIT
3811         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3812         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3813                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3814         test_mkdir -p $DIR/$tdir/d2/test_dir
3815         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3816                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3817         cleanup_test32_mount
3818 }
3819 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3820
3821 test_32e() {
3822         rm -fr $DIR/$tdir
3823         test_mkdir -p $DIR/$tdir/tmp
3824         local tmp_dir=$DIR/$tdir/tmp
3825         ln -s $DIR/$tdir $tmp_dir/symlink11
3826         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3827         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3828         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3829 }
3830 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3831
3832 test_32f() {
3833         rm -fr $DIR/$tdir
3834         test_mkdir -p $DIR/$tdir/tmp
3835         local tmp_dir=$DIR/$tdir/tmp
3836         ln -s $DIR/$tdir $tmp_dir/symlink11
3837         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3838         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3839         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3840 }
3841 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3842
3843 test_32g() {
3844         local tmp_dir=$DIR/$tdir/tmp
3845         test_mkdir -p $tmp_dir
3846         test_mkdir $DIR/${tdir}2
3847         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3848         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3849         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3850         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3851         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3852         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3853 }
3854 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3855
3856 test_32h() {
3857         rm -fr $DIR/$tdir $DIR/${tdir}2
3858         tmp_dir=$DIR/$tdir/tmp
3859         test_mkdir -p $tmp_dir
3860         test_mkdir $DIR/${tdir}2
3861         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3862         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3863         ls $tmp_dir/symlink12 || error "listing symlink12"
3864         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3865 }
3866 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3867
3868 test_32i() {
3869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3870
3871         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3872         trap cleanup_test32_mount EXIT
3873         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3874         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3875                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3876         touch $DIR/$tdir/test_file
3877         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3878                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3879         cleanup_test32_mount
3880 }
3881 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3882
3883 test_32j() {
3884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3885
3886         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3887         trap cleanup_test32_mount EXIT
3888         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3889         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3890                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3891         touch $DIR/$tdir/test_file
3892         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3893                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3894         cleanup_test32_mount
3895 }
3896 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3897
3898 test_32k() {
3899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3900
3901         rm -fr $DIR/$tdir
3902         trap cleanup_test32_mount EXIT
3903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3904         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3905                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3906         test_mkdir -p $DIR/$tdir/d2
3907         touch $DIR/$tdir/d2/test_file || error "touch failed"
3908         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3909                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3910         cleanup_test32_mount
3911 }
3912 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3913
3914 test_32l() {
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         rm -fr $DIR/$tdir
3918         trap cleanup_test32_mount EXIT
3919         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3920         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3921                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3922         test_mkdir -p $DIR/$tdir/d2
3923         touch $DIR/$tdir/d2/test_file || error "touch failed"
3924         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3925                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3926         cleanup_test32_mount
3927 }
3928 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3929
3930 test_32m() {
3931         rm -fr $DIR/d32m
3932         test_mkdir -p $DIR/d32m/tmp
3933         TMP_DIR=$DIR/d32m/tmp
3934         ln -s $DIR $TMP_DIR/symlink11
3935         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3936         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3937                 error "symlink11 not a link"
3938         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3939                 error "symlink01 not a link"
3940 }
3941 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3942
3943 test_32n() {
3944         rm -fr $DIR/d32n
3945         test_mkdir -p $DIR/d32n/tmp
3946         TMP_DIR=$DIR/d32n/tmp
3947         ln -s $DIR $TMP_DIR/symlink11
3948         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3949         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3950         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3951 }
3952 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3953
3954 test_32o() {
3955         touch $DIR/$tfile
3956         test_mkdir -p $DIR/d32o/tmp
3957         TMP_DIR=$DIR/d32o/tmp
3958         ln -s $DIR/$tfile $TMP_DIR/symlink12
3959         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3960         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3961                 error "symlink12 not a link"
3962         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3963         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3964                 error "$DIR/d32o/tmp/symlink12 not file type"
3965         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3966                 error "$DIR/d32o/symlink02 not file type"
3967 }
3968 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3969
3970 test_32p() {
3971         log 32p_1
3972         rm -fr $DIR/d32p
3973         log 32p_2
3974         rm -f $DIR/$tfile
3975         log 32p_3
3976         touch $DIR/$tfile
3977         log 32p_4
3978         test_mkdir -p $DIR/d32p/tmp
3979         log 32p_5
3980         TMP_DIR=$DIR/d32p/tmp
3981         log 32p_6
3982         ln -s $DIR/$tfile $TMP_DIR/symlink12
3983         log 32p_7
3984         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3985         log 32p_8
3986         cat $DIR/d32p/tmp/symlink12 ||
3987                 error "Can't open $DIR/d32p/tmp/symlink12"
3988         log 32p_9
3989         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3990         log 32p_10
3991 }
3992 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3993
3994 test_32q() {
3995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3996
3997         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3998         trap cleanup_test32_mount EXIT
3999         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4000         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4001         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4002                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4003         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4004         cleanup_test32_mount
4005 }
4006 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4007
4008 test_32r() {
4009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4010
4011         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4012         trap cleanup_test32_mount EXIT
4013         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4014         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4015         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4016                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4017         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4018         cleanup_test32_mount
4019 }
4020 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4021
4022 test_33aa() {
4023         rm -f $DIR/$tfile
4024         touch $DIR/$tfile
4025         chmod 444 $DIR/$tfile
4026         chown $RUNAS_ID $DIR/$tfile
4027         log 33_1
4028         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4029         log 33_2
4030 }
4031 run_test 33aa "write file with mode 444 (should return error)"
4032
4033 test_33a() {
4034         rm -fr $DIR/$tdir
4035         test_mkdir $DIR/$tdir
4036         chown $RUNAS_ID $DIR/$tdir
4037         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4038                 error "$RUNAS create $tdir/$tfile failed"
4039         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4040                 error "open RDWR" || true
4041 }
4042 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4043
4044 test_33b() {
4045         rm -fr $DIR/$tdir
4046         test_mkdir $DIR/$tdir
4047         chown $RUNAS_ID $DIR/$tdir
4048         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4049 }
4050 run_test 33b "test open file with malformed flags (No panic)"
4051
4052 test_33c() {
4053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4054         remote_ost_nodsh && skip "remote OST with nodsh"
4055
4056         local ostnum
4057         local ostname
4058         local write_bytes
4059         local all_zeros
4060
4061         all_zeros=true
4062         test_mkdir $DIR/$tdir
4063         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4064
4065         sync
4066         for ostnum in $(seq $OSTCOUNT); do
4067                 # test-framework's OST numbering is one-based, while Lustre's
4068                 # is zero-based
4069                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4070                 # check if at least some write_bytes stats are counted
4071                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4072                               obdfilter.$ostname.stats |
4073                               awk '/^write_bytes/ {print $7}' )
4074                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4075                 if (( ${write_bytes:-0} > 0 )); then
4076                         all_zeros=false
4077                         break
4078                 fi
4079         done
4080
4081         $all_zeros || return 0
4082
4083         # Write four bytes
4084         echo foo > $DIR/$tdir/bar
4085         # Really write them
4086         sync
4087
4088         # Total up write_bytes after writing.  We'd better find non-zeros.
4089         for ostnum in $(seq $OSTCOUNT); do
4090                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4091                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4092                               obdfilter/$ostname/stats |
4093                               awk '/^write_bytes/ {print $7}' )
4094                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4095                 if (( ${write_bytes:-0} > 0 )); then
4096                         all_zeros=false
4097                         break
4098                 fi
4099         done
4100
4101         if $all_zeros; then
4102                 for ostnum in $(seq $OSTCOUNT); do
4103                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4104                         echo "Check write_bytes is in obdfilter.*.stats:"
4105                         do_facet ost$ostnum lctl get_param -n \
4106                                 obdfilter.$ostname.stats
4107                 done
4108                 error "OST not keeping write_bytes stats (b=22312)"
4109         fi
4110 }
4111 run_test 33c "test write_bytes stats"
4112
4113 test_33d() {
4114         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         local MDTIDX=1
4118         local remote_dir=$DIR/$tdir/remote_dir
4119
4120         test_mkdir $DIR/$tdir
4121         $LFS mkdir -i $MDTIDX $remote_dir ||
4122                 error "create remote directory failed"
4123
4124         touch $remote_dir/$tfile
4125         chmod 444 $remote_dir/$tfile
4126         chown $RUNAS_ID $remote_dir/$tfile
4127
4128         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4129
4130         chown $RUNAS_ID $remote_dir
4131         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4132                                         error "create" || true
4133         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4134                                     error "open RDWR" || true
4135         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4136 }
4137 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4138
4139 test_33e() {
4140         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4141
4142         mkdir $DIR/$tdir
4143
4144         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4145         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4146         mkdir $DIR/$tdir/local_dir
4147
4148         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4149         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4150         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4151
4152         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4153                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4154
4155         rmdir $DIR/$tdir/* || error "rmdir failed"
4156
4157         umask 777
4158         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4159         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4160         mkdir $DIR/$tdir/local_dir
4161
4162         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4163         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4164         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4165
4166         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4167                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4168
4169         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4170
4171         umask 000
4172         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4173         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4174         mkdir $DIR/$tdir/local_dir
4175
4176         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4177         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4178         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4179
4180         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4181                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4182 }
4183 run_test 33e "mkdir and striped directory should have same mode"
4184
4185 cleanup_33f() {
4186         trap 0
4187         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4188 }
4189
4190 test_33f() {
4191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4192         remote_mds_nodsh && skip "remote MDS with nodsh"
4193
4194         mkdir $DIR/$tdir
4195         chmod go+rwx $DIR/$tdir
4196         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4197         trap cleanup_33f EXIT
4198
4199         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4200                 error "cannot create striped directory"
4201
4202         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4203                 error "cannot create files in striped directory"
4204
4205         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4206                 error "cannot remove files in striped directory"
4207
4208         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4209                 error "cannot remove striped directory"
4210
4211         cleanup_33f
4212 }
4213 run_test 33f "nonroot user can create, access, and remove a striped directory"
4214
4215 test_33g() {
4216         mkdir -p $DIR/$tdir/dir2
4217
4218         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4219         echo $err
4220         [[ $err =~ "exists" ]] || error "Not exists error"
4221 }
4222 run_test 33g "nonroot user create already existing root created file"
4223
4224 test_33h() {
4225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4226         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4227                 skip "Need MDS version at least 2.13.50"
4228
4229         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4230                 error "mkdir $tdir failed"
4231         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4232
4233         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4234         local index2
4235
4236         for fname in $DIR/$tdir/$tfile.bak \
4237                      $DIR/$tdir/$tfile.SAV \
4238                      $DIR/$tdir/$tfile.orig \
4239                      $DIR/$tdir/$tfile~; do
4240                 touch $fname  || error "touch $fname failed"
4241                 index2=$($LFS getstripe -m $fname)
4242                 [ $index -eq $index2 ] ||
4243                         error "$fname MDT index mismatch $index != $index2"
4244         done
4245
4246         local failed=0
4247         for i in {1..250}; do
4248                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4249                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4250                         touch $fname  || error "touch $fname failed"
4251                         index2=$($LFS getstripe -m $fname)
4252                         if [[ $index != $index2 ]]; then
4253                                 failed=$((failed + 1))
4254                                 echo "$fname MDT index mismatch $index != $index2"
4255                         fi
4256                 done
4257         done
4258         echo "$failed MDT index mismatches"
4259         (( failed < 20 )) || error "MDT index mismatch $failed times"
4260
4261 }
4262 run_test 33h "temp file is located on the same MDT as target"
4263
4264 test_33i()
4265 {
4266         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4267
4268         local FNAME=$(str_repeat 'f' 250)
4269
4270         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4271         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4272
4273         local count
4274         local total
4275
4276         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4277
4278         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4279
4280         lctl --device %$MDC deactivate
4281         stack_trap "lctl --device %$MDC activate"
4282         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4283         total=$(\ls -l $DIR/$tdir | wc -l)
4284         # "ls -l" will list total in the first line
4285         total=$((total - 1))
4286         (( total + count == 1000 )) ||
4287                 error "ls list $total files, $count files on MDT1"
4288 }
4289 run_test 33i "striped directory can be accessed when one MDT is down"
4290
4291 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4292 test_34a() {
4293         rm -f $DIR/f34
4294         $MCREATE $DIR/f34 || error "mcreate failed"
4295         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4296                 error "getstripe failed"
4297         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4298         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4299                 error "getstripe failed"
4300         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4301                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4302 }
4303 run_test 34a "truncate file that has not been opened ==========="
4304
4305 test_34b() {
4306         [ ! -f $DIR/f34 ] && test_34a
4307         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4308                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4309         $OPENFILE -f O_RDONLY $DIR/f34
4310         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4311                 error "getstripe failed"
4312         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4313                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4314 }
4315 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4316
4317 test_34c() {
4318         [ ! -f $DIR/f34 ] && test_34a
4319         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4320                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4321         $OPENFILE -f O_RDWR $DIR/f34
4322         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4323                 error "$LFS getstripe failed"
4324         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4325                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4326 }
4327 run_test 34c "O_RDWR opening file-with-size works =============="
4328
4329 test_34d() {
4330         [ ! -f $DIR/f34 ] && test_34a
4331         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4332                 error "dd failed"
4333         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4334                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4335         rm $DIR/f34
4336 }
4337 run_test 34d "write to sparse file ============================="
4338
4339 test_34e() {
4340         rm -f $DIR/f34e
4341         $MCREATE $DIR/f34e || error "mcreate failed"
4342         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4343         $CHECKSTAT -s 1000 $DIR/f34e ||
4344                 error "Size of $DIR/f34e not equal to 1000 bytes"
4345         $OPENFILE -f O_RDWR $DIR/f34e
4346         $CHECKSTAT -s 1000 $DIR/f34e ||
4347                 error "Size of $DIR/f34e not equal to 1000 bytes"
4348 }
4349 run_test 34e "create objects, some with size and some without =="
4350
4351 test_34f() { # bug 6242, 6243
4352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4353
4354         SIZE34F=48000
4355         rm -f $DIR/f34f
4356         $MCREATE $DIR/f34f || error "mcreate failed"
4357         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4358         dd if=$DIR/f34f of=$TMP/f34f
4359         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4360         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4361         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4362         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4363         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4364 }
4365 run_test 34f "read from a file with no objects until EOF ======="
4366
4367 test_34g() {
4368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4369
4370         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4371                 error "dd failed"
4372         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4373         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4374                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4375         cancel_lru_locks osc
4376         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4377                 error "wrong size after lock cancel"
4378
4379         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4380         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4381                 error "expanding truncate failed"
4382         cancel_lru_locks osc
4383         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4384                 error "wrong expanded size after lock cancel"
4385 }
4386 run_test 34g "truncate long file ==============================="
4387
4388 test_34h() {
4389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4390
4391         local gid=10
4392         local sz=1000
4393
4394         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4395         sync # Flush the cache so that multiop below does not block on cache
4396              # flush when getting the group lock
4397         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4398         MULTIPID=$!
4399
4400         # Since just timed wait is not good enough, let's do a sync write
4401         # that way we are sure enough time for a roundtrip + processing
4402         # passed + 2 seconds of extra margin.
4403         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4404         rm $DIR/${tfile}-1
4405         sleep 2
4406
4407         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4408                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4409                 kill -9 $MULTIPID
4410         fi
4411         wait $MULTIPID
4412         local nsz=`stat -c %s $DIR/$tfile`
4413         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4414 }
4415 run_test 34h "ftruncate file under grouplock should not block"
4416
4417 test_35a() {
4418         cp /bin/sh $DIR/f35a
4419         chmod 444 $DIR/f35a
4420         chown $RUNAS_ID $DIR/f35a
4421         $RUNAS $DIR/f35a && error || true
4422         rm $DIR/f35a
4423 }
4424 run_test 35a "exec file with mode 444 (should return and not leak)"
4425
4426 test_36a() {
4427         rm -f $DIR/f36
4428         utime $DIR/f36 || error "utime failed for MDS"
4429 }
4430 run_test 36a "MDS utime check (mknod, utime)"
4431
4432 test_36b() {
4433         echo "" > $DIR/f36
4434         utime $DIR/f36 || error "utime failed for OST"
4435 }
4436 run_test 36b "OST utime check (open, utime)"
4437
4438 test_36c() {
4439         rm -f $DIR/d36/f36
4440         test_mkdir $DIR/d36
4441         chown $RUNAS_ID $DIR/d36
4442         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4443 }
4444 run_test 36c "non-root MDS utime check (mknod, utime)"
4445
4446 test_36d() {
4447         [ ! -d $DIR/d36 ] && test_36c
4448         echo "" > $DIR/d36/f36
4449         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4450 }
4451 run_test 36d "non-root OST utime check (open, utime)"
4452
4453 test_36e() {
4454         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4455
4456         test_mkdir $DIR/$tdir
4457         touch $DIR/$tdir/$tfile
4458         $RUNAS utime $DIR/$tdir/$tfile &&
4459                 error "utime worked, expected failure" || true
4460 }
4461 run_test 36e "utime on non-owned file (should return error)"
4462
4463 subr_36fh() {
4464         local fl="$1"
4465         local LANG_SAVE=$LANG
4466         local LC_LANG_SAVE=$LC_LANG
4467         export LANG=C LC_LANG=C # for date language
4468
4469         DATESTR="Dec 20  2000"
4470         test_mkdir $DIR/$tdir
4471         lctl set_param fail_loc=$fl
4472         date; date +%s
4473         cp /etc/hosts $DIR/$tdir/$tfile
4474         sync & # write RPC generated with "current" inode timestamp, but delayed
4475         sleep 1
4476         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4477         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4478         cancel_lru_locks $OSC
4479         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4480         date; date +%s
4481         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4482                 echo "BEFORE: $LS_BEFORE" && \
4483                 echo "AFTER : $LS_AFTER" && \
4484                 echo "WANT  : $DATESTR" && \
4485                 error "$DIR/$tdir/$tfile timestamps changed" || true
4486
4487         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4488 }
4489
4490 test_36f() {
4491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4492
4493         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4494         subr_36fh "0x80000214"
4495 }
4496 run_test 36f "utime on file racing with OST BRW write =========="
4497
4498 test_36g() {
4499         remote_ost_nodsh && skip "remote OST with nodsh"
4500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4501         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4502                 skip "Need MDS version at least 2.12.51"
4503
4504         local fmd_max_age
4505         local fmd
4506         local facet="ost1"
4507         local tgt="obdfilter"
4508
4509         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4510
4511         test_mkdir $DIR/$tdir
4512         fmd_max_age=$(do_facet $facet \
4513                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4514                 head -n 1")
4515
4516         echo "FMD max age: ${fmd_max_age}s"
4517         touch $DIR/$tdir/$tfile
4518         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4519                 gawk '{cnt=cnt+$1}  END{print cnt}')
4520         echo "FMD before: $fmd"
4521         [[ $fmd == 0 ]] &&
4522                 error "FMD wasn't create by touch"
4523         sleep $((fmd_max_age + 12))
4524         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4525                 gawk '{cnt=cnt+$1}  END{print cnt}')
4526         echo "FMD after: $fmd"
4527         [[ $fmd == 0 ]] ||
4528                 error "FMD wasn't expired by ping"
4529 }
4530 run_test 36g "FMD cache expiry ====================="
4531
4532 test_36h() {
4533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4534
4535         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4536         subr_36fh "0x80000227"
4537 }
4538 run_test 36h "utime on file racing with OST BRW write =========="
4539
4540 test_36i() {
4541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4542
4543         test_mkdir $DIR/$tdir
4544         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4545
4546         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4547         local new_mtime=$((mtime + 200))
4548
4549         #change Modify time of striped dir
4550         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4551                         error "change mtime failed"
4552
4553         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4554
4555         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4556 }
4557 run_test 36i "change mtime on striped directory"
4558
4559 # test_37 - duplicate with tests 32q 32r
4560
4561 test_38() {
4562         local file=$DIR/$tfile
4563         touch $file
4564         openfile -f O_DIRECTORY $file
4565         local RC=$?
4566         local ENOTDIR=20
4567         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4568         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4569 }
4570 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4571
4572 test_39a() { # was test_39
4573         touch $DIR/$tfile
4574         touch $DIR/${tfile}2
4575 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4576 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4577 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4578         sleep 2
4579         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4580         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4581                 echo "mtime"
4582                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4583                 echo "atime"
4584                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4585                 echo "ctime"
4586                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4587                 error "O_TRUNC didn't change timestamps"
4588         fi
4589 }
4590 run_test 39a "mtime changed on create"
4591
4592 test_39b() {
4593         test_mkdir -c1 $DIR/$tdir
4594         cp -p /etc/passwd $DIR/$tdir/fopen
4595         cp -p /etc/passwd $DIR/$tdir/flink
4596         cp -p /etc/passwd $DIR/$tdir/funlink
4597         cp -p /etc/passwd $DIR/$tdir/frename
4598         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4599
4600         sleep 1
4601         echo "aaaaaa" >> $DIR/$tdir/fopen
4602         echo "aaaaaa" >> $DIR/$tdir/flink
4603         echo "aaaaaa" >> $DIR/$tdir/funlink
4604         echo "aaaaaa" >> $DIR/$tdir/frename
4605
4606         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4607         local link_new=`stat -c %Y $DIR/$tdir/flink`
4608         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4609         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4610
4611         cat $DIR/$tdir/fopen > /dev/null
4612         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4613         rm -f $DIR/$tdir/funlink2
4614         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4615
4616         for (( i=0; i < 2; i++ )) ; do
4617                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4618                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4619                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4620                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4621
4622                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4623                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4624                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4625                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4626
4627                 cancel_lru_locks $OSC
4628                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4629         done
4630 }
4631 run_test 39b "mtime change on open, link, unlink, rename  ======"
4632
4633 # this should be set to past
4634 TEST_39_MTIME=`date -d "1 year ago" +%s`
4635
4636 # bug 11063
4637 test_39c() {
4638         touch $DIR1/$tfile
4639         sleep 2
4640         local mtime0=`stat -c %Y $DIR1/$tfile`
4641
4642         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4643         local mtime1=`stat -c %Y $DIR1/$tfile`
4644         [ "$mtime1" = $TEST_39_MTIME ] || \
4645                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4646
4647         local d1=`date +%s`
4648         echo hello >> $DIR1/$tfile
4649         local d2=`date +%s`
4650         local mtime2=`stat -c %Y $DIR1/$tfile`
4651         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4652                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4653
4654         mv $DIR1/$tfile $DIR1/$tfile-1
4655
4656         for (( i=0; i < 2; i++ )) ; do
4657                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4658                 [ "$mtime2" = "$mtime3" ] || \
4659                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4660
4661                 cancel_lru_locks $OSC
4662                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4663         done
4664 }
4665 run_test 39c "mtime change on rename ==========================="
4666
4667 # bug 21114
4668 test_39d() {
4669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4670
4671         touch $DIR1/$tfile
4672         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4673
4674         for (( i=0; i < 2; i++ )) ; do
4675                 local mtime=`stat -c %Y $DIR1/$tfile`
4676                 [ $mtime = $TEST_39_MTIME ] || \
4677                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4678
4679                 cancel_lru_locks $OSC
4680                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4681         done
4682 }
4683 run_test 39d "create, utime, stat =============================="
4684
4685 # bug 21114
4686 test_39e() {
4687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4688
4689         touch $DIR1/$tfile
4690         local mtime1=`stat -c %Y $DIR1/$tfile`
4691
4692         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4693
4694         for (( i=0; i < 2; i++ )) ; do
4695                 local mtime2=`stat -c %Y $DIR1/$tfile`
4696                 [ $mtime2 = $TEST_39_MTIME ] || \
4697                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4698
4699                 cancel_lru_locks $OSC
4700                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4701         done
4702 }
4703 run_test 39e "create, stat, utime, stat ========================"
4704
4705 # bug 21114
4706 test_39f() {
4707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4708
4709         touch $DIR1/$tfile
4710         mtime1=`stat -c %Y $DIR1/$tfile`
4711
4712         sleep 2
4713         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4714
4715         for (( i=0; i < 2; i++ )) ; do
4716                 local mtime2=`stat -c %Y $DIR1/$tfile`
4717                 [ $mtime2 = $TEST_39_MTIME ] || \
4718                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4719
4720                 cancel_lru_locks $OSC
4721                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4722         done
4723 }
4724 run_test 39f "create, stat, sleep, utime, stat ================="
4725
4726 # bug 11063
4727 test_39g() {
4728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4729
4730         echo hello >> $DIR1/$tfile
4731         local mtime1=`stat -c %Y $DIR1/$tfile`
4732
4733         sleep 2
4734         chmod o+r $DIR1/$tfile
4735
4736         for (( i=0; i < 2; i++ )) ; do
4737                 local mtime2=`stat -c %Y $DIR1/$tfile`
4738                 [ "$mtime1" = "$mtime2" ] || \
4739                         error "lost mtime: $mtime2, should be $mtime1"
4740
4741                 cancel_lru_locks $OSC
4742                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4743         done
4744 }
4745 run_test 39g "write, chmod, stat ==============================="
4746
4747 # bug 11063
4748 test_39h() {
4749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4750
4751         touch $DIR1/$tfile
4752         sleep 1
4753
4754         local d1=`date`
4755         echo hello >> $DIR1/$tfile
4756         local mtime1=`stat -c %Y $DIR1/$tfile`
4757
4758         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4759         local d2=`date`
4760         if [ "$d1" != "$d2" ]; then
4761                 echo "write and touch not within one second"
4762         else
4763                 for (( i=0; i < 2; i++ )) ; do
4764                         local mtime2=`stat -c %Y $DIR1/$tfile`
4765                         [ "$mtime2" = $TEST_39_MTIME ] || \
4766                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4767
4768                         cancel_lru_locks $OSC
4769                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4770                 done
4771         fi
4772 }
4773 run_test 39h "write, utime within one second, stat ============="
4774
4775 test_39i() {
4776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4777
4778         touch $DIR1/$tfile
4779         sleep 1
4780
4781         echo hello >> $DIR1/$tfile
4782         local mtime1=`stat -c %Y $DIR1/$tfile`
4783
4784         mv $DIR1/$tfile $DIR1/$tfile-1
4785
4786         for (( i=0; i < 2; i++ )) ; do
4787                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4788
4789                 [ "$mtime1" = "$mtime2" ] || \
4790                         error "lost mtime: $mtime2, should be $mtime1"
4791
4792                 cancel_lru_locks $OSC
4793                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4794         done
4795 }
4796 run_test 39i "write, rename, stat =============================="
4797
4798 test_39j() {
4799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4800
4801         start_full_debug_logging
4802         touch $DIR1/$tfile
4803         sleep 1
4804
4805         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4806         lctl set_param fail_loc=0x80000412
4807         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4808                 error "multiop failed"
4809         local multipid=$!
4810         local mtime1=`stat -c %Y $DIR1/$tfile`
4811
4812         mv $DIR1/$tfile $DIR1/$tfile-1
4813
4814         kill -USR1 $multipid
4815         wait $multipid || error "multiop close failed"
4816
4817         for (( i=0; i < 2; i++ )) ; do
4818                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4819                 [ "$mtime1" = "$mtime2" ] ||
4820                         error "mtime is lost on close: $mtime2, " \
4821                               "should be $mtime1"
4822
4823                 cancel_lru_locks
4824                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4825         done
4826         lctl set_param fail_loc=0
4827         stop_full_debug_logging
4828 }
4829 run_test 39j "write, rename, close, stat ======================="
4830
4831 test_39k() {
4832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4833
4834         touch $DIR1/$tfile
4835         sleep 1
4836
4837         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4838         local multipid=$!
4839         local mtime1=`stat -c %Y $DIR1/$tfile`
4840
4841         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4842
4843         kill -USR1 $multipid
4844         wait $multipid || error "multiop close failed"
4845
4846         for (( i=0; i < 2; i++ )) ; do
4847                 local mtime2=`stat -c %Y $DIR1/$tfile`
4848
4849                 [ "$mtime2" = $TEST_39_MTIME ] || \
4850                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4851
4852                 cancel_lru_locks
4853                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4854         done
4855 }
4856 run_test 39k "write, utime, close, stat ========================"
4857
4858 # this should be set to future
4859 TEST_39_ATIME=`date -d "1 year" +%s`
4860
4861 test_39l() {
4862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4863         remote_mds_nodsh && skip "remote MDS with nodsh"
4864
4865         local atime_diff=$(do_facet $SINGLEMDS \
4866                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4867         rm -rf $DIR/$tdir
4868         mkdir_on_mdt0 $DIR/$tdir
4869
4870         # test setting directory atime to future
4871         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4872         local atime=$(stat -c %X $DIR/$tdir)
4873         [ "$atime" = $TEST_39_ATIME ] ||
4874                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4875
4876         # test setting directory atime from future to now
4877         local now=$(date +%s)
4878         touch -a -d @$now $DIR/$tdir
4879
4880         atime=$(stat -c %X $DIR/$tdir)
4881         [ "$atime" -eq "$now"  ] ||
4882                 error "atime is not updated from future: $atime, $now"
4883
4884         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4885         sleep 3
4886
4887         # test setting directory atime when now > dir atime + atime_diff
4888         local d1=$(date +%s)
4889         ls $DIR/$tdir
4890         local d2=$(date +%s)
4891         cancel_lru_locks mdc
4892         atime=$(stat -c %X $DIR/$tdir)
4893         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4894                 error "atime is not updated  : $atime, should be $d2"
4895
4896         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4897         sleep 3
4898
4899         # test not setting directory atime when now < dir atime + atime_diff
4900         ls $DIR/$tdir
4901         cancel_lru_locks mdc
4902         atime=$(stat -c %X $DIR/$tdir)
4903         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4904                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4905
4906         do_facet $SINGLEMDS \
4907                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4908 }
4909 run_test 39l "directory atime update ==========================="
4910
4911 test_39m() {
4912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4913
4914         touch $DIR1/$tfile
4915         sleep 2
4916         local far_past_mtime=$(date -d "May 29 1953" +%s)
4917         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4918
4919         touch -m -d @$far_past_mtime $DIR1/$tfile
4920         touch -a -d @$far_past_atime $DIR1/$tfile
4921
4922         for (( i=0; i < 2; i++ )) ; do
4923                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4924                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4925                         error "atime or mtime set incorrectly"
4926
4927                 cancel_lru_locks $OSC
4928                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4929         done
4930 }
4931 run_test 39m "test atime and mtime before 1970"
4932
4933 test_39n() { # LU-3832
4934         remote_mds_nodsh && skip "remote MDS with nodsh"
4935
4936         local atime_diff=$(do_facet $SINGLEMDS \
4937                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4938         local atime0
4939         local atime1
4940         local atime2
4941
4942         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4943
4944         rm -rf $DIR/$tfile
4945         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4946         atime0=$(stat -c %X $DIR/$tfile)
4947
4948         sleep 5
4949         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4950         atime1=$(stat -c %X $DIR/$tfile)
4951
4952         sleep 5
4953         cancel_lru_locks mdc
4954         cancel_lru_locks osc
4955         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4956         atime2=$(stat -c %X $DIR/$tfile)
4957
4958         do_facet $SINGLEMDS \
4959                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4960
4961         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4962         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4963 }
4964 run_test 39n "check that O_NOATIME is honored"
4965
4966 test_39o() {
4967         TESTDIR=$DIR/$tdir/$tfile
4968         [ -e $TESTDIR ] && rm -rf $TESTDIR
4969         mkdir -p $TESTDIR
4970         cd $TESTDIR
4971         links1=2
4972         ls
4973         mkdir a b
4974         ls
4975         links2=$(stat -c %h .)
4976         [ $(($links1 + 2)) != $links2 ] &&
4977                 error "wrong links count $(($links1 + 2)) != $links2"
4978         rmdir b
4979         links3=$(stat -c %h .)
4980         [ $(($links1 + 1)) != $links3 ] &&
4981                 error "wrong links count $links1 != $links3"
4982         return 0
4983 }
4984 run_test 39o "directory cached attributes updated after create"
4985
4986 test_39p() {
4987         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4988
4989         local MDTIDX=1
4990         TESTDIR=$DIR/$tdir/$tdir
4991         [ -e $TESTDIR ] && rm -rf $TESTDIR
4992         test_mkdir -p $TESTDIR
4993         cd $TESTDIR
4994         links1=2
4995         ls
4996         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4997         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4998         ls
4999         links2=$(stat -c %h .)
5000         [ $(($links1 + 2)) != $links2 ] &&
5001                 error "wrong links count $(($links1 + 2)) != $links2"
5002         rmdir remote_dir2
5003         links3=$(stat -c %h .)
5004         [ $(($links1 + 1)) != $links3 ] &&
5005                 error "wrong links count $links1 != $links3"
5006         return 0
5007 }
5008 run_test 39p "remote directory cached attributes updated after create ========"
5009
5010 test_39r() {
5011         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5012                 skip "no atime update on old OST"
5013         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5014                 skip_env "ldiskfs only test"
5015         fi
5016
5017         local saved_adiff
5018         saved_adiff=$(do_facet ost1 \
5019                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5020         stack_trap "do_facet ost1 \
5021                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5022
5023         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5024
5025         $LFS setstripe -i 0 $DIR/$tfile
5026         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5027                 error "can't write initial file"
5028         cancel_lru_locks osc
5029
5030         # exceed atime_diff and access file
5031         sleep 6
5032         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5033                 error "can't udpate atime"
5034
5035         local atime_cli=$(stat -c %X $DIR/$tfile)
5036         echo "client atime: $atime_cli"
5037         # allow atime update to be written to device
5038         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5039         sleep 5
5040
5041         local ostdev=$(ostdevname 1)
5042         local fid=($(lfs getstripe -y $DIR/$tfile |
5043                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5044         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5045         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5046
5047         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5048         local atime_ost=$(do_facet ost1 "$cmd" |&
5049                           awk -F'[: ]' '/atime:/ { print $4 }')
5050         (( atime_cli == atime_ost )) ||
5051                 error "atime on client $atime_cli != ost $atime_ost"
5052 }
5053 run_test 39r "lazy atime update on OST"
5054
5055 test_39q() { # LU-8041
5056         local testdir=$DIR/$tdir
5057         mkdir -p $testdir
5058         multiop_bg_pause $testdir D_c || error "multiop failed"
5059         local multipid=$!
5060         cancel_lru_locks mdc
5061         kill -USR1 $multipid
5062         local atime=$(stat -c %X $testdir)
5063         [ "$atime" -ne 0 ] || error "atime is zero"
5064 }
5065 run_test 39q "close won't zero out atime"
5066
5067 test_40() {
5068         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5069         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5070                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5071         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5072                 error "$tfile is not 4096 bytes in size"
5073 }
5074 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5075
5076 test_41() {
5077         # bug 1553
5078         small_write $DIR/f41 18
5079 }
5080 run_test 41 "test small file write + fstat ====================="
5081
5082 count_ost_writes() {
5083         lctl get_param -n ${OSC}.*.stats |
5084                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5085                         END { printf("%0.0f", writes) }'
5086 }
5087
5088 # decent default
5089 WRITEBACK_SAVE=500
5090 DIRTY_RATIO_SAVE=40
5091 MAX_DIRTY_RATIO=50
5092 BG_DIRTY_RATIO_SAVE=10
5093 MAX_BG_DIRTY_RATIO=25
5094
5095 start_writeback() {
5096         trap 0
5097         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5098         # dirty_ratio, dirty_background_ratio
5099         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5100                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5101                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5102                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5103         else
5104                 # if file not here, we are a 2.4 kernel
5105                 kill -CONT `pidof kupdated`
5106         fi
5107 }
5108
5109 stop_writeback() {
5110         # setup the trap first, so someone cannot exit the test at the
5111         # exact wrong time and mess up a machine
5112         trap start_writeback EXIT
5113         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5114         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5115                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5116                 sysctl -w vm.dirty_writeback_centisecs=0
5117                 sysctl -w vm.dirty_writeback_centisecs=0
5118                 # save and increase /proc/sys/vm/dirty_ratio
5119                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5120                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5121                 # save and increase /proc/sys/vm/dirty_background_ratio
5122                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5123                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5124         else
5125                 # if file not here, we are a 2.4 kernel
5126                 kill -STOP `pidof kupdated`
5127         fi
5128 }
5129
5130 # ensure that all stripes have some grant before we test client-side cache
5131 setup_test42() {
5132         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5133                 dd if=/dev/zero of=$i bs=4k count=1
5134                 rm $i
5135         done
5136 }
5137
5138 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5139 # file truncation, and file removal.
5140 test_42a() {
5141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5142
5143         setup_test42
5144         cancel_lru_locks $OSC
5145         stop_writeback
5146         sync; sleep 1; sync # just to be safe
5147         BEFOREWRITES=`count_ost_writes`
5148         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5149         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5150         AFTERWRITES=`count_ost_writes`
5151         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5152                 error "$BEFOREWRITES < $AFTERWRITES"
5153         start_writeback
5154 }
5155 run_test 42a "ensure that we don't flush on close"
5156
5157 test_42b() {
5158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5159
5160         setup_test42
5161         cancel_lru_locks $OSC
5162         stop_writeback
5163         sync
5164         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5165         BEFOREWRITES=$(count_ost_writes)
5166         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5167         AFTERWRITES=$(count_ost_writes)
5168         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5169                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5170         fi
5171         BEFOREWRITES=$(count_ost_writes)
5172         sync || error "sync: $?"
5173         AFTERWRITES=$(count_ost_writes)
5174         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5175                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5176         fi
5177         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5178         start_writeback
5179         return 0
5180 }
5181 run_test 42b "test destroy of file with cached dirty data ======"
5182
5183 # if these tests just want to test the effect of truncation,
5184 # they have to be very careful.  consider:
5185 # - the first open gets a {0,EOF}PR lock
5186 # - the first write conflicts and gets a {0, count-1}PW
5187 # - the rest of the writes are under {count,EOF}PW
5188 # - the open for truncate tries to match a {0,EOF}PR
5189 #   for the filesize and cancels the PWs.
5190 # any number of fixes (don't get {0,EOF} on open, match
5191 # composite locks, do smarter file size management) fix
5192 # this, but for now we want these tests to verify that
5193 # the cancellation with truncate intent works, so we
5194 # start the file with a full-file pw lock to match against
5195 # until the truncate.
5196 trunc_test() {
5197         test=$1
5198         file=$DIR/$test
5199         offset=$2
5200         cancel_lru_locks $OSC
5201         stop_writeback
5202         # prime the file with 0,EOF PW to match
5203         touch $file
5204         $TRUNCATE $file 0
5205         sync; sync
5206         # now the real test..
5207         dd if=/dev/zero of=$file bs=1024 count=100
5208         BEFOREWRITES=`count_ost_writes`
5209         $TRUNCATE $file $offset
5210         cancel_lru_locks $OSC
5211         AFTERWRITES=`count_ost_writes`
5212         start_writeback
5213 }
5214
5215 test_42c() {
5216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5217
5218         trunc_test 42c 1024
5219         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5220                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5221         rm $file
5222 }
5223 run_test 42c "test partial truncate of file with cached dirty data"
5224
5225 test_42d() {
5226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5227
5228         trunc_test 42d 0
5229         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5230                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5231         rm $file
5232 }
5233 run_test 42d "test complete truncate of file with cached dirty data"
5234
5235 test_42e() { # bug22074
5236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5237
5238         local TDIR=$DIR/${tdir}e
5239         local pages=16 # hardcoded 16 pages, don't change it.
5240         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5241         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5242         local max_dirty_mb
5243         local warmup_files
5244
5245         test_mkdir $DIR/${tdir}e
5246         $LFS setstripe -c 1 $TDIR
5247         createmany -o $TDIR/f $files
5248
5249         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5250
5251         # we assume that with $OSTCOUNT files, at least one of them will
5252         # be allocated on OST0.
5253         warmup_files=$((OSTCOUNT * max_dirty_mb))
5254         createmany -o $TDIR/w $warmup_files
5255
5256         # write a large amount of data into one file and sync, to get good
5257         # avail_grant number from OST.
5258         for ((i=0; i<$warmup_files; i++)); do
5259                 idx=$($LFS getstripe -i $TDIR/w$i)
5260                 [ $idx -ne 0 ] && continue
5261                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5262                 break
5263         done
5264         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5265         sync
5266         $LCTL get_param $proc_osc0/cur_dirty_bytes
5267         $LCTL get_param $proc_osc0/cur_grant_bytes
5268
5269         # create as much dirty pages as we can while not to trigger the actual
5270         # RPCs directly. but depends on the env, VFS may trigger flush during this
5271         # period, hopefully we are good.
5272         for ((i=0; i<$warmup_files; i++)); do
5273                 idx=$($LFS getstripe -i $TDIR/w$i)
5274                 [ $idx -ne 0 ] && continue
5275                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5276         done
5277         $LCTL get_param $proc_osc0/cur_dirty_bytes
5278         $LCTL get_param $proc_osc0/cur_grant_bytes
5279
5280         # perform the real test
5281         $LCTL set_param $proc_osc0/rpc_stats 0
5282         for ((;i<$files; i++)); do
5283                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5284                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5285         done
5286         sync
5287         $LCTL get_param $proc_osc0/rpc_stats
5288
5289         local percent=0
5290         local have_ppr=false
5291         $LCTL get_param $proc_osc0/rpc_stats |
5292                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5293                         # skip lines until we are at the RPC histogram data
5294                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5295                         $have_ppr || continue
5296
5297                         # we only want the percent stat for < 16 pages
5298                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5299
5300                         percent=$((percent + WPCT))
5301                         if [[ $percent -gt 15 ]]; then
5302                                 error "less than 16-pages write RPCs" \
5303                                       "$percent% > 15%"
5304                                 break
5305                         fi
5306                 done
5307         rm -rf $TDIR
5308 }
5309 run_test 42e "verify sub-RPC writes are not done synchronously"
5310
5311 test_43A() { # was test_43
5312         test_mkdir $DIR/$tdir
5313         cp -p /bin/ls $DIR/$tdir/$tfile
5314         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5315         pid=$!
5316         # give multiop a chance to open
5317         sleep 1
5318
5319         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5320         kill -USR1 $pid
5321         # Wait for multiop to exit
5322         wait $pid
5323 }
5324 run_test 43A "execution of file opened for write should return -ETXTBSY"
5325
5326 test_43a() {
5327         test_mkdir $DIR/$tdir
5328         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5329         $DIR/$tdir/sleep 60 &
5330         SLEEP_PID=$!
5331         # Make sure exec of $tdir/sleep wins race with truncate
5332         sleep 1
5333         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5334         kill $SLEEP_PID
5335 }
5336 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5337
5338 test_43b() {
5339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5340
5341         test_mkdir $DIR/$tdir
5342         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5343         $DIR/$tdir/sleep 60 &
5344         SLEEP_PID=$!
5345         # Make sure exec of $tdir/sleep wins race with truncate
5346         sleep 1
5347         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5348         kill $SLEEP_PID
5349 }
5350 run_test 43b "truncate of file being executed should return -ETXTBSY"
5351
5352 test_43c() {
5353         local testdir="$DIR/$tdir"
5354         test_mkdir $testdir
5355         cp $SHELL $testdir/
5356         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5357                 ( cd $testdir && md5sum -c )
5358 }
5359 run_test 43c "md5sum of copy into lustre"
5360
5361 test_44A() { # was test_44
5362         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5363
5364         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5365         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5366 }
5367 run_test 44A "zero length read from a sparse stripe"
5368
5369 test_44a() {
5370         local nstripe=$($LFS getstripe -c -d $DIR)
5371         [ -z "$nstripe" ] && skip "can't get stripe info"
5372         [[ $nstripe -gt $OSTCOUNT ]] &&
5373                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5374
5375         local stride=$($LFS getstripe -S -d $DIR)
5376         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5377                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5378         fi
5379
5380         OFFSETS="0 $((stride/2)) $((stride-1))"
5381         for offset in $OFFSETS; do
5382                 for i in $(seq 0 $((nstripe-1))); do
5383                         local GLOBALOFFSETS=""
5384                         # size in Bytes
5385                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5386                         local myfn=$DIR/d44a-$size
5387                         echo "--------writing $myfn at $size"
5388                         ll_sparseness_write $myfn $size ||
5389                                 error "ll_sparseness_write"
5390                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5391                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5392                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5393
5394                         for j in $(seq 0 $((nstripe-1))); do
5395                                 # size in Bytes
5396                                 size=$((((j + $nstripe )*$stride + $offset)))
5397                                 ll_sparseness_write $myfn $size ||
5398                                         error "ll_sparseness_write"
5399                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5400                         done
5401                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5402                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5403                         rm -f $myfn
5404                 done
5405         done
5406 }
5407 run_test 44a "test sparse pwrite ==============================="
5408
5409 dirty_osc_total() {
5410         tot=0
5411         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5412                 tot=$(($tot + $d))
5413         done
5414         echo $tot
5415 }
5416 do_dirty_record() {
5417         before=`dirty_osc_total`
5418         echo executing "\"$*\""
5419         eval $*
5420         after=`dirty_osc_total`
5421         echo before $before, after $after
5422 }
5423 test_45() {
5424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5425
5426         f="$DIR/f45"
5427         # Obtain grants from OST if it supports it
5428         echo blah > ${f}_grant
5429         stop_writeback
5430         sync
5431         do_dirty_record "echo blah > $f"
5432         [[ $before -eq $after ]] && error "write wasn't cached"
5433         do_dirty_record "> $f"
5434         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5435         do_dirty_record "echo blah > $f"
5436         [[ $before -eq $after ]] && error "write wasn't cached"
5437         do_dirty_record "sync"
5438         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5439         do_dirty_record "echo blah > $f"
5440         [[ $before -eq $after ]] && error "write wasn't cached"
5441         do_dirty_record "cancel_lru_locks osc"
5442         [[ $before -gt $after ]] ||
5443                 error "lock cancellation didn't lower dirty count"
5444         start_writeback
5445 }
5446 run_test 45 "osc io page accounting ============================"
5447
5448 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5449 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5450 # objects offset and an assert hit when an rpc was built with 1023's mapped
5451 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5452 test_46() {
5453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5454
5455         f="$DIR/f46"
5456         stop_writeback
5457         sync
5458         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5459         sync
5460         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5461         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5462         sync
5463         start_writeback
5464 }
5465 run_test 46 "dirtying a previously written page ================"
5466
5467 # test_47 is removed "Device nodes check" is moved to test_28
5468
5469 test_48a() { # bug 2399
5470         [ "$mds1_FSTYPE" = "zfs" ] &&
5471         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5472                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5473
5474         test_mkdir $DIR/$tdir
5475         cd $DIR/$tdir
5476         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5477         test_mkdir $DIR/$tdir
5478         touch foo || error "'touch foo' failed after recreating cwd"
5479         test_mkdir bar
5480         touch .foo || error "'touch .foo' failed after recreating cwd"
5481         test_mkdir .bar
5482         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5483         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5484         cd . || error "'cd .' failed after recreating cwd"
5485         mkdir . && error "'mkdir .' worked after recreating cwd"
5486         rmdir . && error "'rmdir .' worked after recreating cwd"
5487         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5488         cd .. || error "'cd ..' failed after recreating cwd"
5489 }
5490 run_test 48a "Access renamed working dir (should return errors)="
5491
5492 test_48b() { # bug 2399
5493         rm -rf $DIR/$tdir
5494         test_mkdir $DIR/$tdir
5495         cd $DIR/$tdir
5496         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5497         touch foo && error "'touch foo' worked after removing cwd"
5498         mkdir foo && error "'mkdir foo' worked after removing cwd"
5499         touch .foo && error "'touch .foo' worked after removing cwd"
5500         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5501         ls . > /dev/null && error "'ls .' worked after removing cwd"
5502         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5503         mkdir . && error "'mkdir .' worked after removing cwd"
5504         rmdir . && error "'rmdir .' worked after removing cwd"
5505         ln -s . foo && error "'ln -s .' worked after removing cwd"
5506         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5507 }
5508 run_test 48b "Access removed working dir (should return errors)="
5509
5510 test_48c() { # bug 2350
5511         #lctl set_param debug=-1
5512         #set -vx
5513         rm -rf $DIR/$tdir
5514         test_mkdir -p $DIR/$tdir/dir
5515         cd $DIR/$tdir/dir
5516         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5517         $TRACE touch foo && error "touch foo worked after removing cwd"
5518         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5519         touch .foo && error "touch .foo worked after removing cwd"
5520         mkdir .foo && error "mkdir .foo worked after removing cwd"
5521         $TRACE ls . && error "'ls .' worked after removing cwd"
5522         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5523         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5524         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5525         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5526         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5527 }
5528 run_test 48c "Access removed working subdir (should return errors)"
5529
5530 test_48d() { # bug 2350
5531         #lctl set_param debug=-1
5532         #set -vx
5533         rm -rf $DIR/$tdir
5534         test_mkdir -p $DIR/$tdir/dir
5535         cd $DIR/$tdir/dir
5536         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5537         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5538         $TRACE touch foo && error "'touch foo' worked after removing parent"
5539         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5540         touch .foo && error "'touch .foo' worked after removing parent"
5541         mkdir .foo && error "mkdir .foo worked after removing parent"
5542         $TRACE ls . && error "'ls .' worked after removing parent"
5543         $TRACE ls .. && error "'ls ..' worked after removing parent"
5544         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5545         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5546         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5547         true
5548 }
5549 run_test 48d "Access removed parent subdir (should return errors)"
5550
5551 test_48e() { # bug 4134
5552         #lctl set_param debug=-1
5553         #set -vx
5554         rm -rf $DIR/$tdir
5555         test_mkdir -p $DIR/$tdir/dir
5556         cd $DIR/$tdir/dir
5557         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5558         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5559         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5560         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5561         # On a buggy kernel addition of "touch foo" after cd .. will
5562         # produce kernel oops in lookup_hash_it
5563         touch ../foo && error "'cd ..' worked after recreate parent"
5564         cd $DIR
5565         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5566 }
5567 run_test 48e "Access to recreated parent subdir (should return errors)"
5568
5569 test_48f() {
5570         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5571                 skip "need MDS >= 2.13.55"
5572         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5573         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5574                 skip "needs different host for mdt1 mdt2"
5575         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5576
5577         $LFS mkdir -i0 $DIR/$tdir
5578         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5579
5580         for d in sub1 sub2 sub3; do
5581                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5582                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5583                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5584         done
5585
5586         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5587 }
5588 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5589
5590 test_49() { # LU-1030
5591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5592         remote_ost_nodsh && skip "remote OST with nodsh"
5593
5594         # get ost1 size - $FSNAME-OST0000
5595         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5596                 awk '{ print $4 }')
5597         # write 800M at maximum
5598         [[ $ost1_size -lt 2 ]] && ost1_size=2
5599         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5600
5601         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5602         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5603         local dd_pid=$!
5604
5605         # change max_pages_per_rpc while writing the file
5606         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5607         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5608         # loop until dd process exits
5609         while ps ax -opid | grep -wq $dd_pid; do
5610                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5611                 sleep $((RANDOM % 5 + 1))
5612         done
5613         # restore original max_pages_per_rpc
5614         $LCTL set_param $osc1_mppc=$orig_mppc
5615         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5616 }
5617 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5618
5619 test_50() {
5620         # bug 1485
5621         test_mkdir $DIR/$tdir
5622         cd $DIR/$tdir
5623         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5624 }
5625 run_test 50 "special situations: /proc symlinks  ==============="
5626
5627 test_51a() {    # was test_51
5628         # bug 1516 - create an empty entry right after ".." then split dir
5629         test_mkdir -c1 $DIR/$tdir
5630         touch $DIR/$tdir/foo
5631         $MCREATE $DIR/$tdir/bar
5632         rm $DIR/$tdir/foo
5633         createmany -m $DIR/$tdir/longfile 201
5634         FNUM=202
5635         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5636                 $MCREATE $DIR/$tdir/longfile$FNUM
5637                 FNUM=$(($FNUM + 1))
5638                 echo -n "+"
5639         done
5640         echo
5641         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5642 }
5643 run_test 51a "special situations: split htree with empty entry =="
5644
5645 cleanup_print_lfs_df () {
5646         trap 0
5647         $LFS df
5648         $LFS df -i
5649 }
5650
5651 test_51b() {
5652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5653
5654         local dir=$DIR/$tdir
5655         local nrdirs=$((65536 + 100))
5656
5657         # cleanup the directory
5658         rm -fr $dir
5659
5660         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5661
5662         $LFS df
5663         $LFS df -i
5664         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5665         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5666         [[ $numfree -lt $nrdirs ]] &&
5667                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5668
5669         # need to check free space for the directories as well
5670         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5671         numfree=$(( blkfree / $(fs_inode_ksize) ))
5672         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5673
5674         trap cleanup_print_lfs_df EXIT
5675
5676         # create files
5677         createmany -d $dir/d $nrdirs || {
5678                 unlinkmany $dir/d $nrdirs
5679                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5680         }
5681
5682         # really created :
5683         nrdirs=$(ls -U $dir | wc -l)
5684
5685         # unlink all but 100 subdirectories, then check it still works
5686         local left=100
5687         local delete=$((nrdirs - left))
5688
5689         $LFS df
5690         $LFS df -i
5691
5692         # for ldiskfs the nlink count should be 1, but this is OSD specific
5693         # and so this is listed for informational purposes only
5694         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5695         unlinkmany -d $dir/d $delete ||
5696                 error "unlink of first $delete subdirs failed"
5697
5698         echo "nlink between: $(stat -c %h $dir)"
5699         local found=$(ls -U $dir | wc -l)
5700         [ $found -ne $left ] &&
5701                 error "can't find subdirs: found only $found, expected $left"
5702
5703         unlinkmany -d $dir/d $delete $left ||
5704                 error "unlink of second $left subdirs failed"
5705         # regardless of whether the backing filesystem tracks nlink accurately
5706         # or not, the nlink count shouldn't be more than "." and ".." here
5707         local after=$(stat -c %h $dir)
5708         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5709                 echo "nlink after: $after"
5710
5711         cleanup_print_lfs_df
5712 }
5713 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5714
5715 test_51d() {
5716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5717         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5718         local qos_old
5719
5720         test_mkdir $DIR/$tdir
5721         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5722
5723         qos_old=$(do_facet mds1 \
5724                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5725         do_nodes $(comma_list $(mdts_nodes)) \
5726                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5727         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5728                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5729
5730         createmany -o $DIR/$tdir/t- 1000
5731         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5732         for ((n = 0; n < $OSTCOUNT; n++)); do
5733                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5734                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5735                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5736                             '($1 == '$n') { objs += 1 } \
5737                             END { printf("%0.0f", objs) }')
5738                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5739         done
5740         unlinkmany $DIR/$tdir/t- 1000
5741
5742         nlast=0
5743         for ((n = 0; n < $OSTCOUNT; n++)); do
5744                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5745                         { $LFS df && $LFS df -i &&
5746                         error "OST $n has fewer objects vs. OST $nlast" \
5747                               " (${objs[$n]} < ${objs[$nlast]}"; }
5748                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5749                         { $LFS df && $LFS df -i &&
5750                         error "OST $n has fewer objects vs. OST $nlast" \
5751                               " (${objs[$n]} < ${objs[$nlast]}"; }
5752
5753                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5754                         { $LFS df && $LFS df -i &&
5755                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5756                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5757                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5758                         { $LFS df && $LFS df -i &&
5759                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5760                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5761                 nlast=$n
5762         done
5763 }
5764 run_test 51d "check object distribution"
5765
5766 test_51e() {
5767         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5768                 skip_env "ldiskfs only test"
5769         fi
5770
5771         test_mkdir -c1 $DIR/$tdir
5772         test_mkdir -c1 $DIR/$tdir/d0
5773
5774         touch $DIR/$tdir/d0/foo
5775         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5776                 error "file exceed 65000 nlink limit!"
5777         unlinkmany $DIR/$tdir/d0/f- 65001
5778         return 0
5779 }
5780 run_test 51e "check file nlink limit"
5781
5782 test_51f() {
5783         test_mkdir $DIR/$tdir
5784
5785         local max=100000
5786         local ulimit_old=$(ulimit -n)
5787         local spare=20 # number of spare fd's for scripts/libraries, etc.
5788         local mdt=$($LFS getstripe -m $DIR/$tdir)
5789         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5790
5791         echo "MDT$mdt numfree=$numfree, max=$max"
5792         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5793         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5794                 while ! ulimit -n $((numfree + spare)); do
5795                         numfree=$((numfree * 3 / 4))
5796                 done
5797                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5798         else
5799                 echo "left ulimit at $ulimit_old"
5800         fi
5801
5802         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5803                 unlinkmany $DIR/$tdir/f $numfree
5804                 error "create+open $numfree files in $DIR/$tdir failed"
5805         }
5806         ulimit -n $ulimit_old
5807
5808         # if createmany exits at 120s there will be fewer than $numfree files
5809         unlinkmany $DIR/$tdir/f $numfree || true
5810 }
5811 run_test 51f "check many open files limit"
5812
5813 test_52a() {
5814         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5815         test_mkdir $DIR/$tdir
5816         touch $DIR/$tdir/foo
5817         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5818         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5819         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5820         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5821         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5822                                         error "link worked"
5823         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5824         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5825         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5826                                                      error "lsattr"
5827         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5828         cp -r $DIR/$tdir $TMP/
5829         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5830 }
5831 run_test 52a "append-only flag test (should return errors)"
5832
5833 test_52b() {
5834         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5835         test_mkdir $DIR/$tdir
5836         touch $DIR/$tdir/foo
5837         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5838         cat test > $DIR/$tdir/foo && error "cat test worked"
5839         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5840         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5841         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5842                                         error "link worked"
5843         echo foo >> $DIR/$tdir/foo && error "echo worked"
5844         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5845         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5846         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5847         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5848                                                         error "lsattr"
5849         chattr -i $DIR/$tdir/foo || error "chattr failed"
5850
5851         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5852 }
5853 run_test 52b "immutable flag test (should return errors) ======="
5854
5855 test_53() {
5856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5857         remote_mds_nodsh && skip "remote MDS with nodsh"
5858         remote_ost_nodsh && skip "remote OST with nodsh"
5859
5860         local param
5861         local param_seq
5862         local ostname
5863         local mds_last
5864         local mds_last_seq
5865         local ost_last
5866         local ost_last_seq
5867         local ost_last_id
5868         local ostnum
5869         local node
5870         local found=false
5871         local support_last_seq=true
5872
5873         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5874                 support_last_seq=false
5875
5876         # only test MDT0000
5877         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5878         local value
5879         for value in $(do_facet $SINGLEMDS \
5880                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5881                 param=$(echo ${value[0]} | cut -d "=" -f1)
5882                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5883
5884                 if $support_last_seq; then
5885                         param_seq=$(echo $param |
5886                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5887                         mds_last_seq=$(do_facet $SINGLEMDS \
5888                                        $LCTL get_param -n $param_seq)
5889                 fi
5890                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5891
5892                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5893                 node=$(facet_active_host ost$((ostnum+1)))
5894                 param="obdfilter.$ostname.last_id"
5895                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5896                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5897                         ost_last_id=$ost_last
5898
5899                         if $support_last_seq; then
5900                                 ost_last_id=$(echo $ost_last |
5901                                               awk -F':' '{print $2}' |
5902                                               sed -e "s/^0x//g")
5903                                 ost_last_seq=$(echo $ost_last |
5904                                                awk -F':' '{print $1}')
5905                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5906                         fi
5907
5908                         if [[ $ost_last_id != $mds_last ]]; then
5909                                 error "$ost_last_id != $mds_last"
5910                         else
5911                                 found=true
5912                                 break
5913                         fi
5914                 done
5915         done
5916         $found || error "can not match last_seq/last_id for $mdtosc"
5917         return 0
5918 }
5919 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5920
5921 test_54a() {
5922         perl -MSocket -e ';' || skip "no Socket perl module installed"
5923
5924         $SOCKETSERVER $DIR/socket ||
5925                 error "$SOCKETSERVER $DIR/socket failed: $?"
5926         $SOCKETCLIENT $DIR/socket ||
5927                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5928         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5929 }
5930 run_test 54a "unix domain socket test =========================="
5931
5932 test_54b() {
5933         f="$DIR/f54b"
5934         mknod $f c 1 3
5935         chmod 0666 $f
5936         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5937 }
5938 run_test 54b "char device works in lustre ======================"
5939
5940 find_loop_dev() {
5941         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5942         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5943         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5944
5945         for i in $(seq 3 7); do
5946                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5947                 LOOPDEV=$LOOPBASE$i
5948                 LOOPNUM=$i
5949                 break
5950         done
5951 }
5952
5953 cleanup_54c() {
5954         local rc=0
5955         loopdev="$DIR/loop54c"
5956
5957         trap 0
5958         $UMOUNT $DIR/$tdir || rc=$?
5959         losetup -d $loopdev || true
5960         losetup -d $LOOPDEV || true
5961         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5962         return $rc
5963 }
5964
5965 test_54c() {
5966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5967
5968         loopdev="$DIR/loop54c"
5969
5970         find_loop_dev
5971         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5972         trap cleanup_54c EXIT
5973         mknod $loopdev b 7 $LOOPNUM
5974         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5975         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5976         losetup $loopdev $DIR/$tfile ||
5977                 error "can't set up $loopdev for $DIR/$tfile"
5978         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5979         test_mkdir $DIR/$tdir
5980         mount -t ext2 $loopdev $DIR/$tdir ||
5981                 error "error mounting $loopdev on $DIR/$tdir"
5982         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5983                 error "dd write"
5984         df $DIR/$tdir
5985         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5986                 error "dd read"
5987         cleanup_54c
5988 }
5989 run_test 54c "block device works in lustre ====================="
5990
5991 test_54d() {
5992         f="$DIR/f54d"
5993         string="aaaaaa"
5994         mknod $f p
5995         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5996 }
5997 run_test 54d "fifo device works in lustre ======================"
5998
5999 test_54e() {
6000         f="$DIR/f54e"
6001         string="aaaaaa"
6002         cp -aL /dev/console $f
6003         echo $string > $f || error "echo $string to $f failed"
6004 }
6005 run_test 54e "console/tty device works in lustre ======================"
6006
6007 test_56a() {
6008         local numfiles=3
6009         local numdirs=2
6010         local dir=$DIR/$tdir
6011
6012         rm -rf $dir
6013         test_mkdir -p $dir/dir
6014         for i in $(seq $numfiles); do
6015                 touch $dir/file$i
6016                 touch $dir/dir/file$i
6017         done
6018
6019         local numcomp=$($LFS getstripe --component-count $dir)
6020
6021         [[ $numcomp == 0 ]] && numcomp=1
6022
6023         # test lfs getstripe with --recursive
6024         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6025
6026         [[ $filenum -eq $((numfiles * 2)) ]] ||
6027                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6028         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6029         [[ $filenum -eq $numfiles ]] ||
6030                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6031         echo "$LFS getstripe showed obdidx or l_ost_idx"
6032
6033         # test lfs getstripe with file instead of dir
6034         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6035         [[ $filenum -eq 1 ]] ||
6036                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6037         echo "$LFS getstripe file1 passed"
6038
6039         #test lfs getstripe with --verbose
6040         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6041         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6042                 error "$LFS getstripe --verbose $dir: "\
6043                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6044         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6045                 error "$LFS getstripe $dir: showed lmm_magic"
6046
6047         #test lfs getstripe with -v prints lmm_fid
6048         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6049         local countfids=$((numdirs + numfiles * numcomp))
6050         [[ $filenum -eq $countfids ]] ||
6051                 error "$LFS getstripe -v $dir: "\
6052                       "got $filenum want $countfids lmm_fid"
6053         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6054                 error "$LFS getstripe $dir: showed lmm_fid by default"
6055         echo "$LFS getstripe --verbose passed"
6056
6057         #check for FID information
6058         local fid1=$($LFS getstripe --fid $dir/file1)
6059         local fid2=$($LFS getstripe --verbose $dir/file1 |
6060                      awk '/lmm_fid: / { print $2; exit; }')
6061         local fid3=$($LFS path2fid $dir/file1)
6062
6063         [ "$fid1" != "$fid2" ] &&
6064                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6065         [ "$fid1" != "$fid3" ] &&
6066                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6067         echo "$LFS getstripe --fid passed"
6068
6069         #test lfs getstripe with --obd
6070         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6071                 error "$LFS getstripe --obd wrong_uuid: should return error"
6072
6073         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6074
6075         local ostidx=1
6076         local obduuid=$(ostuuid_from_index $ostidx)
6077         local found=$($LFS getstripe -r --obd $obduuid $dir |
6078                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6079
6080         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6081         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6082                 ((filenum--))
6083         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6084                 ((filenum--))
6085
6086         [[ $found -eq $filenum ]] ||
6087                 error "$LFS getstripe --obd: found $found expect $filenum"
6088         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6089                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6090                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6091                 error "$LFS getstripe --obd: should not show file on other obd"
6092         echo "$LFS getstripe --obd passed"
6093 }
6094 run_test 56a "check $LFS getstripe"
6095
6096 test_56b() {
6097         local dir=$DIR/$tdir
6098         local numdirs=3
6099
6100         test_mkdir $dir
6101         for i in $(seq $numdirs); do
6102                 test_mkdir $dir/dir$i
6103         done
6104
6105         # test lfs getdirstripe default mode is non-recursion, which is
6106         # different from lfs getstripe
6107         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6108
6109         [[ $dircnt -eq 1 ]] ||
6110                 error "$LFS getdirstripe: found $dircnt, not 1"
6111         dircnt=$($LFS getdirstripe --recursive $dir |
6112                 grep -c lmv_stripe_count)
6113         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6114                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6115 }
6116 run_test 56b "check $LFS getdirstripe"
6117
6118 test_56c() {
6119         remote_ost_nodsh && skip "remote OST with nodsh"
6120
6121         local ost_idx=0
6122         local ost_name=$(ostname_from_index $ost_idx)
6123         local old_status=$(ost_dev_status $ost_idx)
6124         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6125
6126         [[ -z "$old_status" ]] ||
6127                 skip_env "OST $ost_name is in $old_status status"
6128
6129         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6130         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6131                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6132         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6133                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6134                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6135         fi
6136
6137         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6138                 error "$LFS df -v showing inactive devices"
6139         sleep_maxage
6140
6141         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6142
6143         [[ "$new_status" =~ "D" ]] ||
6144                 error "$ost_name status is '$new_status', missing 'D'"
6145         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6146                 [[ "$new_status" =~ "N" ]] ||
6147                         error "$ost_name status is '$new_status', missing 'N'"
6148         fi
6149         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6150                 [[ "$new_status" =~ "f" ]] ||
6151                         error "$ost_name status is '$new_status', missing 'f'"
6152         fi
6153
6154         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6155         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6156                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6157         [[ -z "$p" ]] && restore_lustre_params < $p || true
6158         sleep_maxage
6159
6160         new_status=$(ost_dev_status $ost_idx)
6161         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6162                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6163         # can't check 'f' as devices may actually be on flash
6164 }
6165 run_test 56c "check 'lfs df' showing device status"
6166
6167 test_56d() {
6168         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6169         local osts=$($LFS df -v $MOUNT | grep -c OST)
6170
6171         $LFS df $MOUNT
6172
6173         (( mdts == MDSCOUNT )) ||
6174                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6175         (( osts == OSTCOUNT )) ||
6176                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6177 }
6178 run_test 56d "'lfs df -v' prints only configured devices"
6179
6180 test_56e() {
6181         err_enoent=2 # No such file or directory
6182         err_eopnotsupp=95 # Operation not supported
6183
6184         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6185         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6186
6187         # Check for handling of path not exists
6188         output=$($LFS df $enoent_mnt 2>&1)
6189         ret=$?
6190
6191         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6192         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6193                 error "expect failure $err_enoent, not $ret"
6194
6195         # Check for handling of non-Lustre FS
6196         output=$($LFS df $notsup_mnt)
6197         ret=$?
6198
6199         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6200         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6201                 error "expect success $err_eopnotsupp, not $ret"
6202
6203         # Check for multiple LustreFS argument
6204         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6205         ret=$?
6206
6207         [[ $output -eq 3 && $ret -eq 0 ]] ||
6208                 error "expect success 3, not $output, rc = $ret"
6209
6210         # Check for correct non-Lustre FS handling among multiple
6211         # LustreFS argument
6212         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6213                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6214         ret=$?
6215
6216         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6217                 error "expect success 2, not $output, rc = $ret"
6218 }
6219 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6220
6221 NUMFILES=3
6222 NUMDIRS=3
6223 setup_56() {
6224         local local_tdir="$1"
6225         local local_numfiles="$2"
6226         local local_numdirs="$3"
6227         local dir_params="$4"
6228         local dir_stripe_params="$5"
6229
6230         if [ ! -d "$local_tdir" ] ; then
6231                 test_mkdir -p $dir_stripe_params $local_tdir
6232                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6233                 for i in $(seq $local_numfiles) ; do
6234                         touch $local_tdir/file$i
6235                 done
6236                 for i in $(seq $local_numdirs) ; do
6237                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6238                         for j in $(seq $local_numfiles) ; do
6239                                 touch $local_tdir/dir$i/file$j
6240                         done
6241                 done
6242         fi
6243 }
6244
6245 setup_56_special() {
6246         local local_tdir=$1
6247         local local_numfiles=$2
6248         local local_numdirs=$3
6249
6250         setup_56 $local_tdir $local_numfiles $local_numdirs
6251
6252         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6253                 for i in $(seq $local_numfiles) ; do
6254                         mknod $local_tdir/loop${i}b b 7 $i
6255                         mknod $local_tdir/null${i}c c 1 3
6256                         ln -s $local_tdir/file1 $local_tdir/link${i}
6257                 done
6258                 for i in $(seq $local_numdirs) ; do
6259                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6260                         mknod $local_tdir/dir$i/null${i}c c 1 3
6261                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6262                 done
6263         fi
6264 }
6265
6266 test_56g() {
6267         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6268         local expected=$(($NUMDIRS + 2))
6269
6270         setup_56 $dir $NUMFILES $NUMDIRS
6271
6272         # test lfs find with -name
6273         for i in $(seq $NUMFILES) ; do
6274                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6275
6276                 [ $nums -eq $expected ] ||
6277                         error "lfs find -name '*$i' $dir wrong: "\
6278                               "found $nums, expected $expected"
6279         done
6280 }
6281 run_test 56g "check lfs find -name"
6282
6283 test_56h() {
6284         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6285         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6286
6287         setup_56 $dir $NUMFILES $NUMDIRS
6288
6289         # test lfs find with ! -name
6290         for i in $(seq $NUMFILES) ; do
6291                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6292
6293                 [ $nums -eq $expected ] ||
6294                         error "lfs find ! -name '*$i' $dir wrong: "\
6295                               "found $nums, expected $expected"
6296         done
6297 }
6298 run_test 56h "check lfs find ! -name"
6299
6300 test_56i() {
6301         local dir=$DIR/$tdir
6302
6303         test_mkdir $dir
6304
6305         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6306         local out=$($cmd)
6307
6308         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6309 }
6310 run_test 56i "check 'lfs find -ost UUID' skips directories"
6311
6312 test_56j() {
6313         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6314
6315         setup_56_special $dir $NUMFILES $NUMDIRS
6316
6317         local expected=$((NUMDIRS + 1))
6318         local cmd="$LFS find -type d $dir"
6319         local nums=$($cmd | wc -l)
6320
6321         [ $nums -eq $expected ] ||
6322                 error "'$cmd' wrong: found $nums, expected $expected"
6323 }
6324 run_test 56j "check lfs find -type d"
6325
6326 test_56k() {
6327         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6328
6329         setup_56_special $dir $NUMFILES $NUMDIRS
6330
6331         local expected=$(((NUMDIRS + 1) * NUMFILES))
6332         local cmd="$LFS find -type f $dir"
6333         local nums=$($cmd | wc -l)
6334
6335         [ $nums -eq $expected ] ||
6336                 error "'$cmd' wrong: found $nums, expected $expected"
6337 }
6338 run_test 56k "check lfs find -type f"
6339
6340 test_56l() {
6341         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6342
6343         setup_56_special $dir $NUMFILES $NUMDIRS
6344
6345         local expected=$((NUMDIRS + NUMFILES))
6346         local cmd="$LFS find -type b $dir"
6347         local nums=$($cmd | wc -l)
6348
6349         [ $nums -eq $expected ] ||
6350                 error "'$cmd' wrong: found $nums, expected $expected"
6351 }
6352 run_test 56l "check lfs find -type b"
6353
6354 test_56m() {
6355         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6356
6357         setup_56_special $dir $NUMFILES $NUMDIRS
6358
6359         local expected=$((NUMDIRS + NUMFILES))
6360         local cmd="$LFS find -type c $dir"
6361         local nums=$($cmd | wc -l)
6362         [ $nums -eq $expected ] ||
6363                 error "'$cmd' wrong: found $nums, expected $expected"
6364 }
6365 run_test 56m "check lfs find -type c"
6366
6367 test_56n() {
6368         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6369         setup_56_special $dir $NUMFILES $NUMDIRS
6370
6371         local expected=$((NUMDIRS + NUMFILES))
6372         local cmd="$LFS find -type l $dir"
6373         local nums=$($cmd | wc -l)
6374
6375         [ $nums -eq $expected ] ||
6376                 error "'$cmd' wrong: found $nums, expected $expected"
6377 }
6378 run_test 56n "check lfs find -type l"
6379
6380 test_56o() {
6381         local dir=$DIR/$tdir
6382
6383         setup_56 $dir $NUMFILES $NUMDIRS
6384         utime $dir/file1 > /dev/null || error "utime (1)"
6385         utime $dir/file2 > /dev/null || error "utime (2)"
6386         utime $dir/dir1 > /dev/null || error "utime (3)"
6387         utime $dir/dir2 > /dev/null || error "utime (4)"
6388         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6389         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6390
6391         local expected=4
6392         local nums=$($LFS find -mtime +0 $dir | wc -l)
6393
6394         [ $nums -eq $expected ] ||
6395                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6396
6397         expected=12
6398         cmd="$LFS find -mtime 0 $dir"
6399         nums=$($cmd | wc -l)
6400         [ $nums -eq $expected ] ||
6401                 error "'$cmd' wrong: found $nums, expected $expected"
6402 }
6403 run_test 56o "check lfs find -mtime for old files"
6404
6405 test_56ob() {
6406         local dir=$DIR/$tdir
6407         local expected=1
6408         local count=0
6409
6410         # just to make sure there is something that won't be found
6411         test_mkdir $dir
6412         touch $dir/$tfile.now
6413
6414         for age in year week day hour min; do
6415                 count=$((count + 1))
6416
6417                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6418                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6419                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6420
6421                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6422                 local nums=$($cmd | wc -l)
6423                 [ $nums -eq $expected ] ||
6424                         error "'$cmd' wrong: found $nums, expected $expected"
6425
6426                 cmd="$LFS find $dir -atime $count${age:0:1}"
6427                 nums=$($cmd | wc -l)
6428                 [ $nums -eq $expected ] ||
6429                         error "'$cmd' wrong: found $nums, expected $expected"
6430         done
6431
6432         sleep 2
6433         cmd="$LFS find $dir -ctime +1s -type f"
6434         nums=$($cmd | wc -l)
6435         (( $nums == $count * 2 + 1)) ||
6436                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6437 }
6438 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6439
6440 test_newerXY_base() {
6441         local x=$1
6442         local y=$2
6443         local dir=$DIR/$tdir
6444         local ref
6445         local negref
6446
6447         if [ $y == "t" ]; then
6448                 if [ $x == "b" ]; then
6449                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6450                 else
6451                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6452                 fi
6453         else
6454                 ref=$DIR/$tfile.newer.$x$y
6455                 touch $ref || error "touch $ref failed"
6456         fi
6457
6458         echo "before = $ref"
6459         sleep 2
6460         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6461         sleep 2
6462         if [ $y == "t" ]; then
6463                 if [ $x == "b" ]; then
6464                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6465                 else
6466                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6467                 fi
6468         else
6469                 negref=$DIR/$tfile.negnewer.$x$y
6470                 touch $negref || error "touch $negref failed"
6471         fi
6472
6473         echo "after = $negref"
6474         local cmd="$LFS find $dir -newer$x$y $ref"
6475         local nums=$(eval $cmd | wc -l)
6476         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6477
6478         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6479                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6480
6481         cmd="$LFS find $dir ! -newer$x$y $negref"
6482         nums=$(eval $cmd | wc -l)
6483         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6484                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6485
6486         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6487         nums=$(eval $cmd | wc -l)
6488         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6489                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6490
6491         rm -rf $DIR/*
6492 }
6493
6494 test_56oc() {
6495         test_newerXY_base "a" "a"
6496         test_newerXY_base "a" "m"
6497         test_newerXY_base "a" "c"
6498         test_newerXY_base "m" "a"
6499         test_newerXY_base "m" "m"
6500         test_newerXY_base "m" "c"
6501         test_newerXY_base "c" "a"
6502         test_newerXY_base "c" "m"
6503         test_newerXY_base "c" "c"
6504
6505         [[ -n "$sles_version" ]] &&
6506                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6507
6508         test_newerXY_base "a" "t"
6509         test_newerXY_base "m" "t"
6510         test_newerXY_base "c" "t"
6511
6512         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6513            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6514                 ! btime_supported && echo "btime unsupported" && return 0
6515
6516         test_newerXY_base "b" "b"
6517         test_newerXY_base "b" "t"
6518 }
6519 run_test 56oc "check lfs find -newerXY work"
6520
6521 btime_supported() {
6522         local dir=$DIR/$tdir
6523         local rc
6524
6525         mkdir -p $dir
6526         touch $dir/$tfile
6527         $LFS find $dir -btime -1d -type f
6528         rc=$?
6529         rm -rf $dir
6530         return $rc
6531 }
6532
6533 test_56od() {
6534         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6535                 ! btime_supported && skip "btime unsupported on MDS"
6536
6537         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6538                 ! btime_supported && skip "btime unsupported on clients"
6539
6540         local dir=$DIR/$tdir
6541         local ref=$DIR/$tfile.ref
6542         local negref=$DIR/$tfile.negref
6543
6544         mkdir $dir || error "mkdir $dir failed"
6545         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6546         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6547         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6548         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6549         touch $ref || error "touch $ref failed"
6550         # sleep 3 seconds at least
6551         sleep 3
6552
6553         local before=$(do_facet mds1 date +%s)
6554         local skew=$(($(date +%s) - before + 1))
6555
6556         if (( skew < 0 && skew > -5 )); then
6557                 sleep $((0 - skew + 1))
6558                 skew=0
6559         fi
6560
6561         # Set the dir stripe params to limit files all on MDT0,
6562         # otherwise we need to calc the max clock skew between
6563         # the client and MDTs.
6564         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6565         sleep 2
6566         touch $negref || error "touch $negref failed"
6567
6568         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6569         local nums=$($cmd | wc -l)
6570         local expected=$(((NUMFILES + 1) * NUMDIRS))
6571
6572         [ $nums -eq $expected ] ||
6573                 error "'$cmd' wrong: found $nums, expected $expected"
6574
6575         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6576         nums=$($cmd | wc -l)
6577         expected=$((NUMFILES + 1))
6578         [ $nums -eq $expected ] ||
6579                 error "'$cmd' wrong: found $nums, expected $expected"
6580
6581         [ $skew -lt 0 ] && return
6582
6583         local after=$(do_facet mds1 date +%s)
6584         local age=$((after - before + 1 + skew))
6585
6586         cmd="$LFS find $dir -btime -${age}s -type f"
6587         nums=$($cmd | wc -l)
6588         expected=$(((NUMFILES + 1) * NUMDIRS))
6589
6590         echo "Clock skew between client and server: $skew, age:$age"
6591         [ $nums -eq $expected ] ||
6592                 error "'$cmd' wrong: found $nums, expected $expected"
6593
6594         expected=$(($NUMDIRS + 1))
6595         cmd="$LFS find $dir -btime -${age}s -type d"
6596         nums=$($cmd | wc -l)
6597         [ $nums -eq $expected ] ||
6598                 error "'$cmd' wrong: found $nums, expected $expected"
6599         rm -f $ref $negref || error "Failed to remove $ref $negref"
6600 }
6601 run_test 56od "check lfs find -btime with units"
6602
6603 test_56p() {
6604         [ $RUNAS_ID -eq $UID ] &&
6605                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6606
6607         local dir=$DIR/$tdir
6608
6609         setup_56 $dir $NUMFILES $NUMDIRS
6610         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6611
6612         local expected=$NUMFILES
6613         local cmd="$LFS find -uid $RUNAS_ID $dir"
6614         local nums=$($cmd | wc -l)
6615
6616         [ $nums -eq $expected ] ||
6617                 error "'$cmd' wrong: found $nums, expected $expected"
6618
6619         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6620         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6621         nums=$($cmd | wc -l)
6622         [ $nums -eq $expected ] ||
6623                 error "'$cmd' wrong: found $nums, expected $expected"
6624 }
6625 run_test 56p "check lfs find -uid and ! -uid"
6626
6627 test_56q() {
6628         [ $RUNAS_ID -eq $UID ] &&
6629                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6630
6631         local dir=$DIR/$tdir
6632
6633         setup_56 $dir $NUMFILES $NUMDIRS
6634         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6635
6636         local expected=$NUMFILES
6637         local cmd="$LFS find -gid $RUNAS_GID $dir"
6638         local nums=$($cmd | wc -l)
6639
6640         [ $nums -eq $expected ] ||
6641                 error "'$cmd' wrong: found $nums, expected $expected"
6642
6643         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6644         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6645         nums=$($cmd | wc -l)
6646         [ $nums -eq $expected ] ||
6647                 error "'$cmd' wrong: found $nums, expected $expected"
6648 }
6649 run_test 56q "check lfs find -gid and ! -gid"
6650
6651 test_56r() {
6652         local dir=$DIR/$tdir
6653
6654         setup_56 $dir $NUMFILES $NUMDIRS
6655
6656         local expected=12
6657         local cmd="$LFS find -size 0 -type f -lazy $dir"
6658         local nums=$($cmd | wc -l)
6659
6660         [ $nums -eq $expected ] ||
6661                 error "'$cmd' wrong: found $nums, expected $expected"
6662         cmd="$LFS find -size 0 -type f $dir"
6663         nums=$($cmd | wc -l)
6664         [ $nums -eq $expected ] ||
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666
6667         expected=0
6668         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6669         nums=$($cmd | wc -l)
6670         [ $nums -eq $expected ] ||
6671                 error "'$cmd' wrong: found $nums, expected $expected"
6672         cmd="$LFS find ! -size 0 -type f $dir"
6673         nums=$($cmd | wc -l)
6674         [ $nums -eq $expected ] ||
6675                 error "'$cmd' wrong: found $nums, expected $expected"
6676
6677         echo "test" > $dir/$tfile
6678         echo "test2" > $dir/$tfile.2 && sync
6679         expected=1
6680         cmd="$LFS find -size 5 -type f -lazy $dir"
6681         nums=$($cmd | wc -l)
6682         [ $nums -eq $expected ] ||
6683                 error "'$cmd' wrong: found $nums, expected $expected"
6684         cmd="$LFS find -size 5 -type f $dir"
6685         nums=$($cmd | wc -l)
6686         [ $nums -eq $expected ] ||
6687                 error "'$cmd' wrong: found $nums, expected $expected"
6688
6689         expected=1
6690         cmd="$LFS find -size +5 -type f -lazy $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694         cmd="$LFS find -size +5 -type f $dir"
6695         nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] ||
6697                 error "'$cmd' wrong: found $nums, expected $expected"
6698
6699         expected=2
6700         cmd="$LFS find -size +0 -type f -lazy $dir"
6701         nums=$($cmd | wc -l)
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704         cmd="$LFS find -size +0 -type f $dir"
6705         nums=$($cmd | wc -l)
6706         [ $nums -eq $expected ] ||
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708
6709         expected=2
6710         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6711         nums=$($cmd | wc -l)
6712         [ $nums -eq $expected ] ||
6713                 error "'$cmd' wrong: found $nums, expected $expected"
6714         cmd="$LFS find ! -size -5 -type f $dir"
6715         nums=$($cmd | wc -l)
6716         [ $nums -eq $expected ] ||
6717                 error "'$cmd' wrong: found $nums, expected $expected"
6718
6719         expected=12
6720         cmd="$LFS find -size -5 -type f -lazy $dir"
6721         nums=$($cmd | wc -l)
6722         [ $nums -eq $expected ] ||
6723                 error "'$cmd' wrong: found $nums, expected $expected"
6724         cmd="$LFS find -size -5 -type f $dir"
6725         nums=$($cmd | wc -l)
6726         [ $nums -eq $expected ] ||
6727                 error "'$cmd' wrong: found $nums, expected $expected"
6728 }
6729 run_test 56r "check lfs find -size works"
6730
6731 test_56ra_sub() {
6732         local expected=$1
6733         local glimpses=$2
6734         local cmd="$3"
6735
6736         cancel_lru_locks $OSC
6737
6738         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6739         local nums=$($cmd | wc -l)
6740
6741         [ $nums -eq $expected ] ||
6742                 error "'$cmd' wrong: found $nums, expected $expected"
6743
6744         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6745
6746         if (( rpcs_before + glimpses != rpcs_after )); then
6747                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6748                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6749
6750                 if [[ $glimpses == 0 ]]; then
6751                         error "'$cmd' should not send glimpse RPCs to OST"
6752                 else
6753                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6754                 fi
6755         fi
6756 }
6757
6758 test_56ra() {
6759         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6760                 skip "MDS < 2.12.58 doesn't return LSOM data"
6761         local dir=$DIR/$tdir
6762         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6763
6764         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6765
6766         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6767         $LCTL set_param -n llite.*.statahead_agl=0
6768         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6771         # open and close all files to ensure LSOM is updated
6772         cancel_lru_locks $OSC
6773         find $dir -type f | xargs cat > /dev/null
6774
6775         #   expect_found  glimpse_rpcs  command_to_run
6776         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6777         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6778         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6779         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6780
6781         echo "test" > $dir/$tfile
6782         echo "test2" > $dir/$tfile.2 && sync
6783         cancel_lru_locks $OSC
6784         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6785
6786         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6787         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6788         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6789         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6790
6791         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6792         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6793         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6794         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6795         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6796         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6797 }
6798 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6799
6800 test_56rb() {
6801         local dir=$DIR/$tdir
6802         local tmp=$TMP/$tfile.log
6803         local mdt_idx;
6804
6805         test_mkdir -p $dir || error "failed to mkdir $dir"
6806         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6807                 error "failed to setstripe $dir/$tfile"
6808         mdt_idx=$($LFS getdirstripe -i $dir)
6809         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6810
6811         stack_trap "rm -f $tmp" EXIT
6812         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6813         ! grep -q obd_uuid $tmp ||
6814                 error "failed to find --size +100K --ost 0 $dir"
6815         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6816         ! grep -q obd_uuid $tmp ||
6817                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6818 }
6819 run_test 56rb "check lfs find --size --ost/--mdt works"
6820
6821 test_56rc() {
6822         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6823         local dir=$DIR/$tdir
6824         local found
6825
6826         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6827         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6828         (( $MDSCOUNT > 2 )) &&
6829                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6830         mkdir $dir/$tdir-{1..10}
6831         touch $dir/$tfile-{1..10}
6832
6833         found=$($LFS find $dir --mdt-count 2 | wc -l)
6834         expect=11
6835         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6836
6837         found=$($LFS find $dir -T +1 | wc -l)
6838         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6839         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6840
6841         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6842         expect=11
6843         (( $found == $expect )) || error "found $found all_char, expect $expect"
6844
6845         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6846         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6847         (( $found == $expect )) || error "found $found all_char, expect $expect"
6848 }
6849 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6850
6851 test_56s() { # LU-611 #LU-9369
6852         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6853
6854         local dir=$DIR/$tdir
6855         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6856
6857         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6858         for i in $(seq $NUMDIRS); do
6859                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6860         done
6861
6862         local expected=$NUMDIRS
6863         local cmd="$LFS find -c $OSTCOUNT $dir"
6864         local nums=$($cmd | wc -l)
6865
6866         [ $nums -eq $expected ] || {
6867                 $LFS getstripe -R $dir
6868                 error "'$cmd' wrong: found $nums, expected $expected"
6869         }
6870
6871         expected=$((NUMDIRS + onestripe))
6872         cmd="$LFS find -stripe-count +0 -type f $dir"
6873         nums=$($cmd | wc -l)
6874         [ $nums -eq $expected ] || {
6875                 $LFS getstripe -R $dir
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877         }
6878
6879         expected=$onestripe
6880         cmd="$LFS find -stripe-count 1 -type f $dir"
6881         nums=$($cmd | wc -l)
6882         [ $nums -eq $expected ] || {
6883                 $LFS getstripe -R $dir
6884                 error "'$cmd' wrong: found $nums, expected $expected"
6885         }
6886
6887         cmd="$LFS find -stripe-count -2 -type f $dir"
6888         nums=$($cmd | wc -l)
6889         [ $nums -eq $expected ] || {
6890                 $LFS getstripe -R $dir
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892         }
6893
6894         expected=0
6895         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6896         nums=$($cmd | wc -l)
6897         [ $nums -eq $expected ] || {
6898                 $LFS getstripe -R $dir
6899                 error "'$cmd' wrong: found $nums, expected $expected"
6900         }
6901 }
6902 run_test 56s "check lfs find -stripe-count works"
6903
6904 test_56t() { # LU-611 #LU-9369
6905         local dir=$DIR/$tdir
6906
6907         setup_56 $dir 0 $NUMDIRS
6908         for i in $(seq $NUMDIRS); do
6909                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6910         done
6911
6912         local expected=$NUMDIRS
6913         local cmd="$LFS find -S 8M $dir"
6914         local nums=$($cmd | wc -l)
6915
6916         [ $nums -eq $expected ] || {
6917                 $LFS getstripe -R $dir
6918                 error "'$cmd' wrong: found $nums, expected $expected"
6919         }
6920         rm -rf $dir
6921
6922         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6923
6924         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6925
6926         expected=$(((NUMDIRS + 1) * NUMFILES))
6927         cmd="$LFS find -stripe-size 512k -type f $dir"
6928         nums=$($cmd | wc -l)
6929         [ $nums -eq $expected ] ||
6930                 error "'$cmd' wrong: found $nums, expected $expected"
6931
6932         cmd="$LFS find -stripe-size +320k -type f $dir"
6933         nums=$($cmd | wc -l)
6934         [ $nums -eq $expected ] ||
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936
6937         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6938         cmd="$LFS find -stripe-size +200k -type f $dir"
6939         nums=$($cmd | wc -l)
6940         [ $nums -eq $expected ] ||
6941                 error "'$cmd' wrong: found $nums, expected $expected"
6942
6943         cmd="$LFS find -stripe-size -640k -type f $dir"
6944         nums=$($cmd | wc -l)
6945         [ $nums -eq $expected ] ||
6946                 error "'$cmd' wrong: found $nums, expected $expected"
6947
6948         expected=4
6949         cmd="$LFS find -stripe-size 256k -type f $dir"
6950         nums=$($cmd | wc -l)
6951         [ $nums -eq $expected ] ||
6952                 error "'$cmd' wrong: found $nums, expected $expected"
6953
6954         cmd="$LFS find -stripe-size -320k -type f $dir"
6955         nums=$($cmd | wc -l)
6956         [ $nums -eq $expected ] ||
6957                 error "'$cmd' wrong: found $nums, expected $expected"
6958
6959         expected=0
6960         cmd="$LFS find -stripe-size 1024k -type f $dir"
6961         nums=$($cmd | wc -l)
6962         [ $nums -eq $expected ] ||
6963                 error "'$cmd' wrong: found $nums, expected $expected"
6964 }
6965 run_test 56t "check lfs find -stripe-size works"
6966
6967 test_56u() { # LU-611
6968         local dir=$DIR/$tdir
6969
6970         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6971
6972         if [[ $OSTCOUNT -gt 1 ]]; then
6973                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6974                 onestripe=4
6975         else
6976                 onestripe=0
6977         fi
6978
6979         local expected=$(((NUMDIRS + 1) * NUMFILES))
6980         local cmd="$LFS find -stripe-index 0 -type f $dir"
6981         local nums=$($cmd | wc -l)
6982
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985
6986         expected=$onestripe
6987         cmd="$LFS find -stripe-index 1 -type f $dir"
6988         nums=$($cmd | wc -l)
6989         [ $nums -eq $expected ] ||
6990                 error "'$cmd' wrong: found $nums, expected $expected"
6991
6992         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996
6997         expected=0
6998         # This should produce an error and not return any files
6999         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7000         nums=$($cmd 2>/dev/null | wc -l)
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         if [[ $OSTCOUNT -gt 1 ]]; then
7005                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7006                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7007                 nums=$($cmd | wc -l)
7008                 [ $nums -eq $expected ] ||
7009                         error "'$cmd' wrong: found $nums, expected $expected"
7010         fi
7011 }
7012 run_test 56u "check lfs find -stripe-index works"
7013
7014 test_56v() {
7015         local mdt_idx=0
7016         local dir=$DIR/$tdir
7017
7018         setup_56 $dir $NUMFILES $NUMDIRS
7019
7020         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7021         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7022
7023         for file in $($LFS find -m $UUID $dir); do
7024                 file_midx=$($LFS getstripe -m $file)
7025                 [ $file_midx -eq $mdt_idx ] ||
7026                         error "lfs find -m $UUID != getstripe -m $file_midx"
7027         done
7028 }
7029 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7030
7031 test_56w() {
7032         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7034
7035         local dir=$DIR/$tdir
7036
7037         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7038
7039         local stripe_size=$($LFS getstripe -S -d $dir) ||
7040                 error "$LFS getstripe -S -d $dir failed"
7041         stripe_size=${stripe_size%% *}
7042
7043         local file_size=$((stripe_size * OSTCOUNT))
7044         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7045         local required_space=$((file_num * file_size))
7046         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7047                            head -n1)
7048         [[ $free_space -le $((required_space / 1024)) ]] &&
7049                 skip_env "need $required_space, have $free_space kbytes"
7050
7051         local dd_bs=65536
7052         local dd_count=$((file_size / dd_bs))
7053
7054         # write data into the files
7055         local i
7056         local j
7057         local file
7058
7059         for i in $(seq $NUMFILES); do
7060                 file=$dir/file$i
7061                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7062                         error "write data into $file failed"
7063         done
7064         for i in $(seq $NUMDIRS); do
7065                 for j in $(seq $NUMFILES); do
7066                         file=$dir/dir$i/file$j
7067                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7068                                 error "write data into $file failed"
7069                 done
7070         done
7071
7072         # $LFS_MIGRATE will fail if hard link migration is unsupported
7073         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7074                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7075                         error "creating links to $dir/dir1/file1 failed"
7076         fi
7077
7078         local expected=-1
7079
7080         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7081
7082         # lfs_migrate file
7083         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7084
7085         echo "$cmd"
7086         eval $cmd || error "$cmd failed"
7087
7088         check_stripe_count $dir/file1 $expected
7089
7090         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7091         then
7092                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7093                 # OST 1 if it is on OST 0. This file is small enough to
7094                 # be on only one stripe.
7095                 file=$dir/migr_1_ost
7096                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7097                         error "write data into $file failed"
7098                 local obdidx=$($LFS getstripe -i $file)
7099                 local oldmd5=$(md5sum $file)
7100                 local newobdidx=0
7101
7102                 [[ $obdidx -eq 0 ]] && newobdidx=1
7103                 cmd="$LFS migrate -i $newobdidx $file"
7104                 echo $cmd
7105                 eval $cmd || error "$cmd failed"
7106
7107                 local realobdix=$($LFS getstripe -i $file)
7108                 local newmd5=$(md5sum $file)
7109
7110                 [[ $newobdidx -ne $realobdix ]] &&
7111                         error "new OST is different (was=$obdidx, "\
7112                               "wanted=$newobdidx, got=$realobdix)"
7113                 [[ "$oldmd5" != "$newmd5" ]] &&
7114                         error "md5sum differ: $oldmd5, $newmd5"
7115         fi
7116
7117         # lfs_migrate dir
7118         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7119         echo "$cmd"
7120         eval $cmd || error "$cmd failed"
7121
7122         for j in $(seq $NUMFILES); do
7123                 check_stripe_count $dir/dir1/file$j $expected
7124         done
7125
7126         # lfs_migrate works with lfs find
7127         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7128              $LFS_MIGRATE -y -c $expected"
7129         echo "$cmd"
7130         eval $cmd || error "$cmd failed"
7131
7132         for i in $(seq 2 $NUMFILES); do
7133                 check_stripe_count $dir/file$i $expected
7134         done
7135         for i in $(seq 2 $NUMDIRS); do
7136                 for j in $(seq $NUMFILES); do
7137                 check_stripe_count $dir/dir$i/file$j $expected
7138                 done
7139         done
7140 }
7141 run_test 56w "check lfs_migrate -c stripe_count works"
7142
7143 test_56wb() {
7144         local file1=$DIR/$tdir/file1
7145         local create_pool=false
7146         local initial_pool=$($LFS getstripe -p $DIR)
7147         local pool_list=()
7148         local pool=""
7149
7150         echo -n "Creating test dir..."
7151         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7152         echo "done."
7153
7154         echo -n "Creating test file..."
7155         touch $file1 || error "cannot create file"
7156         echo "done."
7157
7158         echo -n "Detecting existing pools..."
7159         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7160
7161         if [ ${#pool_list[@]} -gt 0 ]; then
7162                 echo "${pool_list[@]}"
7163                 for thispool in "${pool_list[@]}"; do
7164                         if [[ -z "$initial_pool" ||
7165                               "$initial_pool" != "$thispool" ]]; then
7166                                 pool="$thispool"
7167                                 echo "Using existing pool '$pool'"
7168                                 break
7169                         fi
7170                 done
7171         else
7172                 echo "none detected."
7173         fi
7174         if [ -z "$pool" ]; then
7175                 pool=${POOL:-testpool}
7176                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7177                 echo -n "Creating pool '$pool'..."
7178                 create_pool=true
7179                 pool_add $pool &> /dev/null ||
7180                         error "pool_add failed"
7181                 echo "done."
7182
7183                 echo -n "Adding target to pool..."
7184                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7185                         error "pool_add_targets failed"
7186                 echo "done."
7187         fi
7188
7189         echo -n "Setting pool using -p option..."
7190         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7191                 error "migrate failed rc = $?"
7192         echo "done."
7193
7194         echo -n "Verifying test file is in pool after migrating..."
7195         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7196                 error "file was not migrated to pool $pool"
7197         echo "done."
7198
7199         echo -n "Removing test file from pool '$pool'..."
7200         # "lfs migrate $file" won't remove the file from the pool
7201         # until some striping information is changed.
7202         $LFS migrate -c 1 $file1 &> /dev/null ||
7203                 error "cannot remove from pool"
7204         [ "$($LFS getstripe -p $file1)" ] &&
7205                 error "pool still set"
7206         echo "done."
7207
7208         echo -n "Setting pool using --pool option..."
7209         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7210                 error "migrate failed rc = $?"
7211         echo "done."
7212
7213         # Clean up
7214         rm -f $file1
7215         if $create_pool; then
7216                 destroy_test_pools 2> /dev/null ||
7217                         error "destroy test pools failed"
7218         fi
7219 }
7220 run_test 56wb "check lfs_migrate pool support"
7221
7222 test_56wc() {
7223         local file1="$DIR/$tdir/file1"
7224         local parent_ssize
7225         local parent_scount
7226         local cur_ssize
7227         local cur_scount
7228         local orig_ssize
7229
7230         echo -n "Creating test dir..."
7231         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7232         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7233                 error "cannot set stripe by '-S 1M -c 1'"
7234         echo "done"
7235
7236         echo -n "Setting initial stripe for test file..."
7237         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7238                 error "cannot set stripe"
7239         cur_ssize=$($LFS getstripe -S "$file1")
7240         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7241         echo "done."
7242
7243         # File currently set to -S 512K -c 1
7244
7245         # Ensure -c and -S options are rejected when -R is set
7246         echo -n "Verifying incompatible options are detected..."
7247         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7248                 error "incompatible -c and -R options not detected"
7249         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7250                 error "incompatible -S and -R options not detected"
7251         echo "done."
7252
7253         # Ensure unrecognized options are passed through to 'lfs migrate'
7254         echo -n "Verifying -S option is passed through to lfs migrate..."
7255         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7256                 error "migration failed"
7257         cur_ssize=$($LFS getstripe -S "$file1")
7258         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7259         echo "done."
7260
7261         # File currently set to -S 1M -c 1
7262
7263         # Ensure long options are supported
7264         echo -n "Verifying long options supported..."
7265         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7266                 error "long option without argument not supported"
7267         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7268                 error "long option with argument not supported"
7269         cur_ssize=$($LFS getstripe -S "$file1")
7270         [ $cur_ssize -eq 524288 ] ||
7271                 error "migrate --stripe-size $cur_ssize != 524288"
7272         echo "done."
7273
7274         # File currently set to -S 512K -c 1
7275
7276         if [ "$OSTCOUNT" -gt 1 ]; then
7277                 echo -n "Verifying explicit stripe count can be set..."
7278                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7279                         error "migrate failed"
7280                 cur_scount=$($LFS getstripe -c "$file1")
7281                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7282                 echo "done."
7283         fi
7284
7285         # File currently set to -S 512K -c 1 or -S 512K -c 2
7286
7287         # Ensure parent striping is used if -R is set, and no stripe
7288         # count or size is specified
7289         echo -n "Setting stripe for parent directory..."
7290         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7291                 error "cannot set stripe '-S 2M -c 1'"
7292         echo "done."
7293
7294         echo -n "Verifying restripe option uses parent stripe settings..."
7295         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7296         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7297         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7298                 error "migrate failed"
7299         cur_ssize=$($LFS getstripe -S "$file1")
7300         [ $cur_ssize -eq $parent_ssize ] ||
7301                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7302         cur_scount=$($LFS getstripe -c "$file1")
7303         [ $cur_scount -eq $parent_scount ] ||
7304                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7305         echo "done."
7306
7307         # File currently set to -S 1M -c 1
7308
7309         # Ensure striping is preserved if -R is not set, and no stripe
7310         # count or size is specified
7311         echo -n "Verifying striping size preserved when not specified..."
7312         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7313         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7314                 error "cannot set stripe on parent directory"
7315         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7316                 error "migrate failed"
7317         cur_ssize=$($LFS getstripe -S "$file1")
7318         [ $cur_ssize -eq $orig_ssize ] ||
7319                 error "migrate by default $cur_ssize != $orig_ssize"
7320         echo "done."
7321
7322         # Ensure file name properly detected when final option has no argument
7323         echo -n "Verifying file name properly detected..."
7324         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7325                 error "file name interpreted as option argument"
7326         echo "done."
7327
7328         # Clean up
7329         rm -f "$file1"
7330 }
7331 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7332
7333 test_56wd() {
7334         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7335
7336         local file1=$DIR/$tdir/file1
7337
7338         echo -n "Creating test dir..."
7339         test_mkdir $DIR/$tdir || error "cannot create dir"
7340         echo "done."
7341
7342         echo -n "Creating test file..."
7343         touch $file1
7344         echo "done."
7345
7346         # Ensure 'lfs migrate' will fail by using a non-existent option,
7347         # and make sure rsync is not called to recover
7348         echo -n "Make sure --no-rsync option works..."
7349         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7350                 grep -q 'refusing to fall back to rsync' ||
7351                 error "rsync was called with --no-rsync set"
7352         echo "done."
7353
7354         # Ensure rsync is called without trying 'lfs migrate' first
7355         echo -n "Make sure --rsync option works..."
7356         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7357                 grep -q 'falling back to rsync' &&
7358                 error "lfs migrate was called with --rsync set"
7359         echo "done."
7360
7361         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7362         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7363                 grep -q 'at the same time' ||
7364                 error "--rsync and --no-rsync accepted concurrently"
7365         echo "done."
7366
7367         # Clean up
7368         rm -f $file1
7369 }
7370 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7371
7372 test_56we() {
7373         local td=$DIR/$tdir
7374         local tf=$td/$tfile
7375
7376         test_mkdir $td || error "cannot create $td"
7377         touch $tf || error "cannot touch $tf"
7378
7379         echo -n "Make sure --non-direct|-D works..."
7380         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7381                 grep -q "lfs migrate --non-direct" ||
7382                 error "--non-direct option cannot work correctly"
7383         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7384                 grep -q "lfs migrate -D" ||
7385                 error "-D option cannot work correctly"
7386         echo "done."
7387 }
7388 run_test 56we "check lfs_migrate --non-direct|-D support"
7389
7390 test_56x() {
7391         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7392         check_swap_layouts_support
7393
7394         local dir=$DIR/$tdir
7395         local ref1=/etc/passwd
7396         local file1=$dir/file1
7397
7398         test_mkdir $dir || error "creating dir $dir"
7399         $LFS setstripe -c 2 $file1
7400         cp $ref1 $file1
7401         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7402         stripe=$($LFS getstripe -c $file1)
7403         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7404         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7405
7406         # clean up
7407         rm -f $file1
7408 }
7409 run_test 56x "lfs migration support"
7410
7411 test_56xa() {
7412         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7413         check_swap_layouts_support
7414
7415         local dir=$DIR/$tdir/$testnum
7416
7417         test_mkdir -p $dir
7418
7419         local ref1=/etc/passwd
7420         local file1=$dir/file1
7421
7422         $LFS setstripe -c 2 $file1
7423         cp $ref1 $file1
7424         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7425
7426         local stripe=$($LFS getstripe -c $file1)
7427
7428         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7429         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7430
7431         # clean up
7432         rm -f $file1
7433 }
7434 run_test 56xa "lfs migration --block support"
7435
7436 check_migrate_links() {
7437         local dir="$1"
7438         local file1="$dir/file1"
7439         local begin="$2"
7440         local count="$3"
7441         local runas="$4"
7442         local total_count=$(($begin + $count - 1))
7443         local symlink_count=10
7444         local uniq_count=10
7445
7446         if [ ! -f "$file1" ]; then
7447                 echo -n "creating initial file..."
7448                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7449                         error "cannot setstripe initial file"
7450                 echo "done"
7451
7452                 echo -n "creating symlinks..."
7453                 for s in $(seq 1 $symlink_count); do
7454                         ln -s "$file1" "$dir/slink$s" ||
7455                                 error "cannot create symlinks"
7456                 done
7457                 echo "done"
7458
7459                 echo -n "creating nonlinked files..."
7460                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7461                         error "cannot create nonlinked files"
7462                 echo "done"
7463         fi
7464
7465         # create hard links
7466         if [ ! -f "$dir/file$total_count" ]; then
7467                 echo -n "creating hard links $begin:$total_count..."
7468                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7469                         /dev/null || error "cannot create hard links"
7470                 echo "done"
7471         fi
7472
7473         echo -n "checking number of hard links listed in xattrs..."
7474         local fid=$($LFS getstripe -F "$file1")
7475         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7476
7477         echo "${#paths[*]}"
7478         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7479                         skip "hard link list has unexpected size, skipping test"
7480         fi
7481         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7482                         error "link names should exceed xattrs size"
7483         fi
7484
7485         echo -n "migrating files..."
7486         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7487         local rc=$?
7488         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7489         echo "done"
7490
7491         # make sure all links have been properly migrated
7492         echo -n "verifying files..."
7493         fid=$($LFS getstripe -F "$file1") ||
7494                 error "cannot get fid for file $file1"
7495         for i in $(seq 2 $total_count); do
7496                 local fid2=$($LFS getstripe -F $dir/file$i)
7497
7498                 [ "$fid2" == "$fid" ] ||
7499                         error "migrated hard link has mismatched FID"
7500         done
7501
7502         # make sure hard links were properly detected, and migration was
7503         # performed only once for the entire link set; nonlinked files should
7504         # also be migrated
7505         local actual=$(grep -c 'done' <<< "$migrate_out")
7506         local expected=$(($uniq_count + 1))
7507
7508         [ "$actual" -eq  "$expected" ] ||
7509                 error "hard links individually migrated ($actual != $expected)"
7510
7511         # make sure the correct number of hard links are present
7512         local hardlinks=$(stat -c '%h' "$file1")
7513
7514         [ $hardlinks -eq $total_count ] ||
7515                 error "num hard links $hardlinks != $total_count"
7516         echo "done"
7517
7518         return 0
7519 }
7520
7521 test_56xb() {
7522         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7523                 skip "Need MDS version at least 2.10.55"
7524
7525         local dir="$DIR/$tdir"
7526
7527         test_mkdir "$dir" || error "cannot create dir $dir"
7528
7529         echo "testing lfs migrate mode when all links fit within xattrs"
7530         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7531
7532         echo "testing rsync mode when all links fit within xattrs"
7533         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7534
7535         echo "testing lfs migrate mode when all links do not fit within xattrs"
7536         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7537
7538         echo "testing rsync mode when all links do not fit within xattrs"
7539         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7540
7541         chown -R $RUNAS_ID $dir
7542         echo "testing non-root lfs migrate mode when not all links are in xattr"
7543         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7544
7545         # clean up
7546         rm -rf $dir
7547 }
7548 run_test 56xb "lfs migration hard link support"
7549
7550 test_56xc() {
7551         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7552
7553         local dir="$DIR/$tdir"
7554
7555         test_mkdir "$dir" || error "cannot create dir $dir"
7556
7557         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7558         echo -n "Setting initial stripe for 20MB test file..."
7559         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7560                 error "cannot setstripe 20MB file"
7561         echo "done"
7562         echo -n "Sizing 20MB test file..."
7563         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7564         echo "done"
7565         echo -n "Verifying small file autostripe count is 1..."
7566         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7567                 error "cannot migrate 20MB file"
7568         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7569                 error "cannot get stripe for $dir/20mb"
7570         [ $stripe_count -eq 1 ] ||
7571                 error "unexpected stripe count $stripe_count for 20MB file"
7572         rm -f "$dir/20mb"
7573         echo "done"
7574
7575         # Test 2: File is small enough to fit within the available space on
7576         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7577         # have at least an additional 1KB for each desired stripe for test 3
7578         echo -n "Setting stripe for 1GB test file..."
7579         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7580         echo "done"
7581         echo -n "Sizing 1GB test file..."
7582         # File size is 1GB + 3KB
7583         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7584         echo "done"
7585
7586         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7587         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7588         if (( avail > 524288 * OSTCOUNT )); then
7589                 echo -n "Migrating 1GB file..."
7590                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7591                         error "cannot migrate 1GB file"
7592                 echo "done"
7593                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7594                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7595                         error "cannot getstripe for 1GB file"
7596                 [ $stripe_count -eq 2 ] ||
7597                         error "unexpected stripe count $stripe_count != 2"
7598                 echo "done"
7599         fi
7600
7601         # Test 3: File is too large to fit within the available space on
7602         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7603         if [ $OSTCOUNT -ge 3 ]; then
7604                 # The required available space is calculated as
7605                 # file size (1GB + 3KB) / OST count (3).
7606                 local kb_per_ost=349526
7607
7608                 echo -n "Migrating 1GB file with limit..."
7609                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7610                         error "cannot migrate 1GB file with limit"
7611                 echo "done"
7612
7613                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7614                 echo -n "Verifying 1GB autostripe count with limited space..."
7615                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7616                         error "unexpected stripe count $stripe_count (min 3)"
7617                 echo "done"
7618         fi
7619
7620         # clean up
7621         rm -rf $dir
7622 }
7623 run_test 56xc "lfs migration autostripe"
7624
7625 test_56xd() {
7626         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7627
7628         local dir=$DIR/$tdir
7629         local f_mgrt=$dir/$tfile.mgrt
7630         local f_yaml=$dir/$tfile.yaml
7631         local f_copy=$dir/$tfile.copy
7632         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7633         local layout_copy="-c 2 -S 2M -i 1"
7634         local yamlfile=$dir/yamlfile
7635         local layout_before;
7636         local layout_after;
7637
7638         test_mkdir "$dir" || error "cannot create dir $dir"
7639         $LFS setstripe $layout_yaml $f_yaml ||
7640                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7641         $LFS getstripe --yaml $f_yaml > $yamlfile
7642         $LFS setstripe $layout_copy $f_copy ||
7643                 error "cannot setstripe $f_copy with layout $layout_copy"
7644         touch $f_mgrt
7645         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7646
7647         # 1. test option --yaml
7648         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7649                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7650         layout_before=$(get_layout_param $f_yaml)
7651         layout_after=$(get_layout_param $f_mgrt)
7652         [ "$layout_after" == "$layout_before" ] ||
7653                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7654
7655         # 2. test option --copy
7656         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7657                 error "cannot migrate $f_mgrt with --copy $f_copy"
7658         layout_before=$(get_layout_param $f_copy)
7659         layout_after=$(get_layout_param $f_mgrt)
7660         [ "$layout_after" == "$layout_before" ] ||
7661                 error "lfs_migrate --copy: $layout_after != $layout_before"
7662 }
7663 run_test 56xd "check lfs_migrate --yaml and --copy support"
7664
7665 test_56xe() {
7666         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7667
7668         local dir=$DIR/$tdir
7669         local f_comp=$dir/$tfile
7670         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7671         local layout_before=""
7672         local layout_after=""
7673
7674         test_mkdir "$dir" || error "cannot create dir $dir"
7675         $LFS setstripe $layout $f_comp ||
7676                 error "cannot setstripe $f_comp with layout $layout"
7677         layout_before=$(get_layout_param $f_comp)
7678         dd if=/dev/zero of=$f_comp bs=1M count=4
7679
7680         # 1. migrate a comp layout file by lfs_migrate
7681         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7682         layout_after=$(get_layout_param $f_comp)
7683         [ "$layout_before" == "$layout_after" ] ||
7684                 error "lfs_migrate: $layout_before != $layout_after"
7685
7686         # 2. migrate a comp layout file by lfs migrate
7687         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7688         layout_after=$(get_layout_param $f_comp)
7689         [ "$layout_before" == "$layout_after" ] ||
7690                 error "lfs migrate: $layout_before != $layout_after"
7691 }
7692 run_test 56xe "migrate a composite layout file"
7693
7694 test_56xf() {
7695         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7696
7697         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7698                 skip "Need server version at least 2.13.53"
7699
7700         local dir=$DIR/$tdir
7701         local f_comp=$dir/$tfile
7702         local layout="-E 1M -c1 -E -1 -c2"
7703         local fid_before=""
7704         local fid_after=""
7705
7706         test_mkdir "$dir" || error "cannot create dir $dir"
7707         $LFS setstripe $layout $f_comp ||
7708                 error "cannot setstripe $f_comp with layout $layout"
7709         fid_before=$($LFS getstripe --fid $f_comp)
7710         dd if=/dev/zero of=$f_comp bs=1M count=4
7711
7712         # 1. migrate a comp layout file to a comp layout
7713         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7714         fid_after=$($LFS getstripe --fid $f_comp)
7715         [ "$fid_before" == "$fid_after" ] ||
7716                 error "comp-to-comp migrate: $fid_before != $fid_after"
7717
7718         # 2. migrate a comp layout file to a plain layout
7719         $LFS migrate -c2 $f_comp ||
7720                 error "cannot migrate $f_comp by lfs migrate"
7721         fid_after=$($LFS getstripe --fid $f_comp)
7722         [ "$fid_before" == "$fid_after" ] ||
7723                 error "comp-to-plain migrate: $fid_before != $fid_after"
7724
7725         # 3. migrate a plain layout file to a comp layout
7726         $LFS migrate $layout $f_comp ||
7727                 error "cannot migrate $f_comp by lfs migrate"
7728         fid_after=$($LFS getstripe --fid $f_comp)
7729         [ "$fid_before" == "$fid_after" ] ||
7730                 error "plain-to-comp migrate: $fid_before != $fid_after"
7731 }
7732 run_test 56xf "FID is not lost during migration of a composite layout file"
7733
7734 check_file_ost_range() {
7735         local file="$1"
7736         shift
7737         local range="$*"
7738         local -a file_range
7739         local idx
7740
7741         file_range=($($LFS getstripe -y "$file" |
7742                 awk '/l_ost_idx:/ { print $NF }'))
7743
7744         if [[ "${#file_range[@]}" = 0 ]]; then
7745                 echo "No osts found for $file"
7746                 return 1
7747         fi
7748
7749         for idx in "${file_range[@]}"; do
7750                 [[ " $range " =~ " $idx " ]] ||
7751                         return 1
7752         done
7753
7754         return 0
7755 }
7756
7757 sub_test_56xg() {
7758         local stripe_opt="$1"
7759         local pool="$2"
7760         shift 2
7761         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7762
7763         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7764                 error "Fail to migrate $tfile on $pool"
7765         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7766                 error "$tfile is not in pool $pool"
7767         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7768                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7769 }
7770
7771 test_56xg() {
7772         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7773         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7774         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7775                 skip "Need MDS version newer than 2.14.52"
7776
7777         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7778         local -a pool_ranges=("0 0" "1 1" "0 1")
7779
7780         # init pools
7781         for i in "${!pool_names[@]}"; do
7782                 pool_add ${pool_names[$i]} ||
7783                         error "pool_add failed (pool: ${pool_names[$i]})"
7784                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7785                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7786         done
7787
7788         # init the file to migrate
7789         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7790                 error "Unable to create $tfile on OST1"
7791         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7792                 error "Unable to write on $tfile"
7793
7794         echo "1. migrate $tfile on pool ${pool_names[0]}"
7795         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7796
7797         echo "2. migrate $tfile on pool ${pool_names[2]}"
7798         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7799
7800         echo "3. migrate $tfile on pool ${pool_names[1]}"
7801         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7802
7803         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7804         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7805         echo
7806
7807         # Clean pools
7808         destroy_test_pools ||
7809                 error "pool_destroy failed"
7810 }
7811 run_test 56xg "lfs migrate pool support"
7812
7813 test_56y() {
7814         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7815                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7816
7817         local res=""
7818         local dir=$DIR/$tdir
7819         local f1=$dir/file1
7820         local f2=$dir/file2
7821
7822         test_mkdir -p $dir || error "creating dir $dir"
7823         touch $f1 || error "creating std file $f1"
7824         $MULTIOP $f2 H2c || error "creating released file $f2"
7825
7826         # a directory can be raid0, so ask only for files
7827         res=$($LFS find $dir -L raid0 -type f | wc -l)
7828         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7829
7830         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7831         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7832
7833         # only files can be released, so no need to force file search
7834         res=$($LFS find $dir -L released)
7835         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7836
7837         res=$($LFS find $dir -type f \! -L released)
7838         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7839 }
7840 run_test 56y "lfs find -L raid0|released"
7841
7842 test_56z() { # LU-4824
7843         # This checks to make sure 'lfs find' continues after errors
7844         # There are two classes of errors that should be caught:
7845         # - If multiple paths are provided, all should be searched even if one
7846         #   errors out
7847         # - If errors are encountered during the search, it should not terminate
7848         #   early
7849         local dir=$DIR/$tdir
7850         local i
7851
7852         test_mkdir $dir
7853         for i in d{0..9}; do
7854                 test_mkdir $dir/$i
7855                 touch $dir/$i/$tfile
7856         done
7857         $LFS find $DIR/non_existent_dir $dir &&
7858                 error "$LFS find did not return an error"
7859         # Make a directory unsearchable. This should NOT be the last entry in
7860         # directory order.  Arbitrarily pick the 6th entry
7861         chmod 700 $($LFS find $dir -type d | sed '6!d')
7862
7863         $RUNAS $LFS find $DIR/non_existent $dir
7864         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7865
7866         # The user should be able to see 10 directories and 9 files
7867         (( count == 19 )) ||
7868                 error "$LFS find found $count != 19 entries after error"
7869 }
7870 run_test 56z "lfs find should continue after an error"
7871
7872 test_56aa() { # LU-5937
7873         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7874
7875         local dir=$DIR/$tdir
7876
7877         mkdir $dir
7878         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7879
7880         createmany -o $dir/striped_dir/${tfile}- 1024
7881         local dirs=$($LFS find --size +8k $dir/)
7882
7883         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7884 }
7885 run_test 56aa "lfs find --size under striped dir"
7886
7887 test_56ab() { # LU-10705
7888         test_mkdir $DIR/$tdir
7889         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7890         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7891         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7892         # Flush writes to ensure valid blocks.  Need to be more thorough for
7893         # ZFS, since blocks are not allocated/returned to client immediately.
7894         sync_all_data
7895         wait_zfs_commit ost1 2
7896         cancel_lru_locks osc
7897         ls -ls $DIR/$tdir
7898
7899         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7900
7901         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7902
7903         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7904         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7905
7906         rm -f $DIR/$tdir/$tfile.[123]
7907 }
7908 run_test 56ab "lfs find --blocks"
7909
7910 # LU-11188
7911 test_56aca() {
7912         local dir="$DIR/$tdir"
7913         local perms=(001 002 003 004 005 006 007
7914                      010 020 030 040 050 060 070
7915                      100 200 300 400 500 600 700
7916                      111 222 333 444 555 666 777)
7917         local perm_minus=(8 8 4 8 4 4 2
7918                           8 8 4 8 4 4 2
7919                           8 8 4 8 4 4 2
7920                           4 4 2 4 2 2 1)
7921         local perm_slash=(8  8 12  8 12 12 14
7922                           8  8 12  8 12 12 14
7923                           8  8 12  8 12 12 14
7924                          16 16 24 16 24 24 28)
7925
7926         test_mkdir "$dir"
7927         for perm in ${perms[*]}; do
7928                 touch "$dir/$tfile.$perm"
7929                 chmod $perm "$dir/$tfile.$perm"
7930         done
7931
7932         for ((i = 0; i < ${#perms[*]}; i++)); do
7933                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7934                 (( $num == 1 )) ||
7935                         error "lfs find -perm ${perms[i]}:"\
7936                               "$num != 1"
7937
7938                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7939                 (( $num == ${perm_minus[i]} )) ||
7940                         error "lfs find -perm -${perms[i]}:"\
7941                               "$num != ${perm_minus[i]}"
7942
7943                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7944                 (( $num == ${perm_slash[i]} )) ||
7945                         error "lfs find -perm /${perms[i]}:"\
7946                               "$num != ${perm_slash[i]}"
7947         done
7948 }
7949 run_test 56aca "check lfs find -perm with octal representation"
7950
7951 test_56acb() {
7952         local dir=$DIR/$tdir
7953         # p is the permission of write and execute for user, group and other
7954         # without the umask. It is used to test +wx.
7955         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7956         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7957         local symbolic=(+t  a+t u+t g+t o+t
7958                         g+s u+s o+s +s o+sr
7959                         o=r,ug+o,u+w
7960                         u+ g+ o+ a+ ugo+
7961                         u- g- o- a- ugo-
7962                         u= g= o= a= ugo=
7963                         o=r,ug+o,u+w u=r,a+u,u+w
7964                         g=r,ugo=g,u+w u+x,+X +X
7965                         u+x,u+X u+X u+x,g+X o+r,+X
7966                         u+x,go+X +wx +rwx)
7967
7968         test_mkdir $dir
7969         for perm in ${perms[*]}; do
7970                 touch "$dir/$tfile.$perm"
7971                 chmod $perm "$dir/$tfile.$perm"
7972         done
7973
7974         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7975                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7976
7977                 (( $num == 1 )) ||
7978                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7979         done
7980 }
7981 run_test 56acb "check lfs find -perm with symbolic representation"
7982
7983 test_56acc() {
7984         local dir=$DIR/$tdir
7985         local tests="17777 787 789 abcd
7986                 ug=uu ug=a ug=gu uo=ou urw
7987                 u+xg+x a=r,u+x,"
7988
7989         test_mkdir $dir
7990         for err in $tests; do
7991                 if $LFS find $dir -perm $err 2>/dev/null; then
7992                         error "lfs find -perm $err: parsing should have failed"
7993                 fi
7994         done
7995 }
7996 run_test 56acc "check parsing error for lfs find -perm"
7997
7998 test_56ba() {
7999         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8000                 skip "Need MDS version at least 2.10.50"
8001
8002         # Create composite files with one component
8003         local dir=$DIR/$tdir
8004
8005         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8006         # Create composite files with three components
8007         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8008         # Create non-composite files
8009         createmany -o $dir/${tfile}- 10
8010
8011         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8012
8013         [[ $nfiles == 10 ]] ||
8014                 error "lfs find -E 1M found $nfiles != 10 files"
8015
8016         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8017         [[ $nfiles == 25 ]] ||
8018                 error "lfs find ! -E 1M found $nfiles != 25 files"
8019
8020         # All files have a component that starts at 0
8021         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8022         [[ $nfiles == 35 ]] ||
8023                 error "lfs find --component-start 0 - $nfiles != 35 files"
8024
8025         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8026         [[ $nfiles == 15 ]] ||
8027                 error "lfs find --component-start 2M - $nfiles != 15 files"
8028
8029         # All files created here have a componenet that does not starts at 2M
8030         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8031         [[ $nfiles == 35 ]] ||
8032                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8033
8034         # Find files with a specified number of components
8035         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8036         [[ $nfiles == 15 ]] ||
8037                 error "lfs find --component-count 3 - $nfiles != 15 files"
8038
8039         # Remember non-composite files have a component count of zero
8040         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8041         [[ $nfiles == 10 ]] ||
8042                 error "lfs find --component-count 0 - $nfiles != 10 files"
8043
8044         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8045         [[ $nfiles == 20 ]] ||
8046                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8047
8048         # All files have a flag called "init"
8049         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8050         [[ $nfiles == 35 ]] ||
8051                 error "lfs find --component-flags init - $nfiles != 35 files"
8052
8053         # Multi-component files will have a component not initialized
8054         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8055         [[ $nfiles == 15 ]] ||
8056                 error "lfs find !--component-flags init - $nfiles != 15 files"
8057
8058         rm -rf $dir
8059
8060 }
8061 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8062
8063 test_56ca() {
8064         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8065                 skip "Need MDS version at least 2.10.57"
8066
8067         local td=$DIR/$tdir
8068         local tf=$td/$tfile
8069         local dir
8070         local nfiles
8071         local cmd
8072         local i
8073         local j
8074
8075         # create mirrored directories and mirrored files
8076         mkdir $td || error "mkdir $td failed"
8077         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8078         createmany -o $tf- 10 || error "create $tf- failed"
8079
8080         for i in $(seq 2); do
8081                 dir=$td/dir$i
8082                 mkdir $dir || error "mkdir $dir failed"
8083                 $LFS mirror create -N$((3 + i)) $dir ||
8084                         error "create mirrored dir $dir failed"
8085                 createmany -o $dir/$tfile- 10 ||
8086                         error "create $dir/$tfile- failed"
8087         done
8088
8089         # change the states of some mirrored files
8090         echo foo > $tf-6
8091         for i in $(seq 2); do
8092                 dir=$td/dir$i
8093                 for j in $(seq 4 9); do
8094                         echo foo > $dir/$tfile-$j
8095                 done
8096         done
8097
8098         # find mirrored files with specific mirror count
8099         cmd="$LFS find --mirror-count 3 --type f $td"
8100         nfiles=$($cmd | wc -l)
8101         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8102
8103         cmd="$LFS find ! --mirror-count 3 --type f $td"
8104         nfiles=$($cmd | wc -l)
8105         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8106
8107         cmd="$LFS find --mirror-count +2 --type f $td"
8108         nfiles=$($cmd | wc -l)
8109         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8110
8111         cmd="$LFS find --mirror-count -6 --type f $td"
8112         nfiles=$($cmd | wc -l)
8113         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8114
8115         # find mirrored files with specific file state
8116         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8117         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8118
8119         cmd="$LFS find --mirror-state=ro --type f $td"
8120         nfiles=$($cmd | wc -l)
8121         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8122
8123         cmd="$LFS find ! --mirror-state=ro --type f $td"
8124         nfiles=$($cmd | wc -l)
8125         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8126
8127         cmd="$LFS find --mirror-state=wp --type f $td"
8128         nfiles=$($cmd | wc -l)
8129         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8130
8131         cmd="$LFS find ! --mirror-state=sp --type f $td"
8132         nfiles=$($cmd | wc -l)
8133         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8134 }
8135 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8136
8137 test_56da() { # LU-14179
8138         local path=$DIR/$tdir
8139
8140         test_mkdir $path
8141         cd $path
8142
8143         local longdir=$(str_repeat 'a' 255)
8144
8145         for i in {1..15}; do
8146                 path=$path/$longdir
8147                 test_mkdir $longdir
8148                 cd $longdir
8149         done
8150
8151         local len=${#path}
8152         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8153
8154         test_mkdir $lastdir
8155         cd $lastdir
8156         # PATH_MAX-1
8157         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8158
8159         # NAME_MAX
8160         touch $(str_repeat 'f' 255)
8161
8162         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8163                 error "lfs find reported an error"
8164
8165         rm -rf $DIR/$tdir
8166 }
8167 run_test 56da "test lfs find with long paths"
8168
8169 test_57a() {
8170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8171         # note test will not do anything if MDS is not local
8172         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8173                 skip_env "ldiskfs only test"
8174         fi
8175         remote_mds_nodsh && skip "remote MDS with nodsh"
8176
8177         local MNTDEV="osd*.*MDT*.mntdev"
8178         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8179         [ -z "$DEV" ] && error "can't access $MNTDEV"
8180         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8181                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8182                         error "can't access $DEV"
8183                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8184                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8185                 rm $TMP/t57a.dump
8186         done
8187 }
8188 run_test 57a "verify MDS filesystem created with large inodes =="
8189
8190 test_57b() {
8191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8192         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8193                 skip_env "ldiskfs only test"
8194         fi
8195         remote_mds_nodsh && skip "remote MDS with nodsh"
8196
8197         local dir=$DIR/$tdir
8198         local filecount=100
8199         local file1=$dir/f1
8200         local fileN=$dir/f$filecount
8201
8202         rm -rf $dir || error "removing $dir"
8203         test_mkdir -c1 $dir
8204         local mdtidx=$($LFS getstripe -m $dir)
8205         local mdtname=MDT$(printf %04x $mdtidx)
8206         local facet=mds$((mdtidx + 1))
8207
8208         echo "mcreating $filecount files"
8209         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8210
8211         # verify that files do not have EAs yet
8212         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8213                 error "$file1 has an EA"
8214         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8215                 error "$fileN has an EA"
8216
8217         sync
8218         sleep 1
8219         df $dir  #make sure we get new statfs data
8220         local mdsfree=$(do_facet $facet \
8221                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8222         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8223         local file
8224
8225         echo "opening files to create objects/EAs"
8226         for file in $(seq -f $dir/f%g 1 $filecount); do
8227                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8228                         error "opening $file"
8229         done
8230
8231         # verify that files have EAs now
8232         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8233         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8234
8235         sleep 1  #make sure we get new statfs data
8236         df $dir
8237         local mdsfree2=$(do_facet $facet \
8238                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8239         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8240
8241         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8242                 if [ "$mdsfree" != "$mdsfree2" ]; then
8243                         error "MDC before $mdcfree != after $mdcfree2"
8244                 else
8245                         echo "MDC before $mdcfree != after $mdcfree2"
8246                         echo "unable to confirm if MDS has large inodes"
8247                 fi
8248         fi
8249         rm -rf $dir
8250 }
8251 run_test 57b "default LOV EAs are stored inside large inodes ==="
8252
8253 test_58() {
8254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8255         [ -z "$(which wiretest 2>/dev/null)" ] &&
8256                         skip_env "could not find wiretest"
8257
8258         wiretest
8259 }
8260 run_test 58 "verify cross-platform wire constants =============="
8261
8262 test_59() {
8263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8264
8265         echo "touch 130 files"
8266         createmany -o $DIR/f59- 130
8267         echo "rm 130 files"
8268         unlinkmany $DIR/f59- 130
8269         sync
8270         # wait for commitment of removal
8271         wait_delete_completed
8272 }
8273 run_test 59 "verify cancellation of llog records async ========="
8274
8275 TEST60_HEAD="test_60 run $RANDOM"
8276 test_60a() {
8277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8278         remote_mgs_nodsh && skip "remote MGS with nodsh"
8279         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8280                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8281                         skip_env "missing subtest run-llog.sh"
8282
8283         log "$TEST60_HEAD - from kernel mode"
8284         do_facet mgs "$LCTL dk > /dev/null"
8285         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8286         do_facet mgs $LCTL dk > $TMP/$tfile
8287
8288         # LU-6388: test llog_reader
8289         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8290         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8291         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8292                         skip_env "missing llog_reader"
8293         local fstype=$(facet_fstype mgs)
8294         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8295                 skip_env "Only for ldiskfs or zfs type mgs"
8296
8297         local mntpt=$(facet_mntpt mgs)
8298         local mgsdev=$(mgsdevname 1)
8299         local fid_list
8300         local fid
8301         local rec_list
8302         local rec
8303         local rec_type
8304         local obj_file
8305         local path
8306         local seq
8307         local oid
8308         local pass=true
8309
8310         #get fid and record list
8311         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8312                 tail -n 4))
8313         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8314                 tail -n 4))
8315         #remount mgs as ldiskfs or zfs type
8316         stop mgs || error "stop mgs failed"
8317         mount_fstype mgs || error "remount mgs failed"
8318         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8319                 fid=${fid_list[i]}
8320                 rec=${rec_list[i]}
8321                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8322                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8323                 oid=$((16#$oid))
8324
8325                 case $fstype in
8326                         ldiskfs )
8327                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8328                         zfs )
8329                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8330                 esac
8331                 echo "obj_file is $obj_file"
8332                 do_facet mgs $llog_reader $obj_file
8333
8334                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8335                         awk '{ print $3 }' | sed -e "s/^type=//g")
8336                 if [ $rec_type != $rec ]; then
8337                         echo "FAILED test_60a wrong record type $rec_type," \
8338                               "should be $rec"
8339                         pass=false
8340                         break
8341                 fi
8342
8343                 #check obj path if record type is LLOG_LOGID_MAGIC
8344                 if [ "$rec" == "1064553b" ]; then
8345                         path=$(do_facet mgs $llog_reader $obj_file |
8346                                 grep "path=" | awk '{ print $NF }' |
8347                                 sed -e "s/^path=//g")
8348                         if [ $obj_file != $mntpt/$path ]; then
8349                                 echo "FAILED test_60a wrong obj path" \
8350                                       "$montpt/$path, should be $obj_file"
8351                                 pass=false
8352                                 break
8353                         fi
8354                 fi
8355         done
8356         rm -f $TMP/$tfile
8357         #restart mgs before "error", otherwise it will block the next test
8358         stop mgs || error "stop mgs failed"
8359         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8360         $pass || error "test failed, see FAILED test_60a messages for specifics"
8361 }
8362 run_test 60a "llog_test run from kernel module and test llog_reader"
8363
8364 test_60b() { # bug 6411
8365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8366
8367         dmesg > $DIR/$tfile
8368         LLOG_COUNT=$(do_facet mgs dmesg |
8369                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8370                           /llog_[a-z]*.c:[0-9]/ {
8371                                 if (marker)
8372                                         from_marker++
8373                                 from_begin++
8374                           }
8375                           END {
8376                                 if (marker)
8377                                         print from_marker
8378                                 else
8379                                         print from_begin
8380                           }")
8381
8382         [[ $LLOG_COUNT -gt 120 ]] &&
8383                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8384 }
8385 run_test 60b "limit repeated messages from CERROR/CWARN"
8386
8387 test_60c() {
8388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8389
8390         echo "create 5000 files"
8391         createmany -o $DIR/f60c- 5000
8392 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8393         lctl set_param fail_loc=0x80000137
8394         unlinkmany $DIR/f60c- 5000
8395         lctl set_param fail_loc=0
8396 }
8397 run_test 60c "unlink file when mds full"
8398
8399 test_60d() {
8400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8401
8402         SAVEPRINTK=$(lctl get_param -n printk)
8403         # verify "lctl mark" is even working"
8404         MESSAGE="test message ID $RANDOM $$"
8405         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8406         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8407
8408         lctl set_param printk=0 || error "set lnet.printk failed"
8409         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8410         MESSAGE="new test message ID $RANDOM $$"
8411         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8412         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8413         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8414
8415         lctl set_param -n printk="$SAVEPRINTK"
8416 }
8417 run_test 60d "test printk console message masking"
8418
8419 test_60e() {
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8421         remote_mds_nodsh && skip "remote MDS with nodsh"
8422
8423         touch $DIR/$tfile
8424 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8425         do_facet mds1 lctl set_param fail_loc=0x15b
8426         rm $DIR/$tfile
8427 }
8428 run_test 60e "no space while new llog is being created"
8429
8430 test_60f() {
8431         local old_path=$($LCTL get_param -n debug_path)
8432
8433         stack_trap "$LCTL set_param debug_path=$old_path"
8434         stack_trap "rm -f $TMP/$tfile*"
8435         rm -f $TMP/$tfile* 2> /dev/null
8436         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8437         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8438         test_mkdir $DIR/$tdir
8439         # retry in case the open is cached and not released
8440         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8441                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8442                 sleep 0.1
8443         done
8444         ls $TMP/$tfile*
8445         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8446 }
8447 run_test 60f "change debug_path works"
8448
8449 test_60g() {
8450         local pid
8451         local i
8452
8453         test_mkdir -c $MDSCOUNT $DIR/$tdir
8454
8455         (
8456                 local index=0
8457                 while true; do
8458                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8459                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8460                                 2>/dev/null
8461                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8462                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8463                         index=$((index + 1))
8464                 done
8465         ) &
8466
8467         pid=$!
8468
8469         for i in {0..100}; do
8470                 # define OBD_FAIL_OSD_TXN_START    0x19a
8471                 local index=$((i % MDSCOUNT + 1))
8472
8473                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8474                         > /dev/null
8475                 sleep 0.01
8476         done
8477
8478         kill -9 $pid
8479
8480         for i in $(seq $MDSCOUNT); do
8481                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8482         done
8483
8484         mkdir $DIR/$tdir/new || error "mkdir failed"
8485         rmdir $DIR/$tdir/new || error "rmdir failed"
8486
8487         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8488                 -t namespace
8489         for i in $(seq $MDSCOUNT); do
8490                 wait_update_facet mds$i "$LCTL get_param -n \
8491                         mdd.$(facet_svc mds$i).lfsck_namespace |
8492                         awk '/^status/ { print \\\$2 }'" "completed"
8493         done
8494
8495         ls -R $DIR/$tdir
8496         rm -rf $DIR/$tdir || error "rmdir failed"
8497 }
8498 run_test 60g "transaction abort won't cause MDT hung"
8499
8500 test_60h() {
8501         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8502                 skip "Need MDS version at least 2.12.52"
8503         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8504
8505         local f
8506
8507         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8508         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8509         for fail_loc in 0x80000188 0x80000189; do
8510                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8511                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8512                         error "mkdir $dir-$fail_loc failed"
8513                 for i in {0..10}; do
8514                         # create may fail on missing stripe
8515                         echo $i > $DIR/$tdir-$fail_loc/$i
8516                 done
8517                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8518                         error "getdirstripe $tdir-$fail_loc failed"
8519                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8520                         error "migrate $tdir-$fail_loc failed"
8521                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8522                         error "getdirstripe $tdir-$fail_loc failed"
8523                 pushd $DIR/$tdir-$fail_loc
8524                 for f in *; do
8525                         echo $f | cmp $f - || error "$f data mismatch"
8526                 done
8527                 popd
8528                 rm -rf $DIR/$tdir-$fail_loc
8529         done
8530 }
8531 run_test 60h "striped directory with missing stripes can be accessed"
8532
8533 function t60i_load() {
8534         mkdir $DIR/$tdir
8535         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8536         $LCTL set_param fail_loc=0x131c fail_val=1
8537         for ((i=0; i<5000; i++)); do
8538                 touch $DIR/$tdir/f$i
8539         done
8540 }
8541
8542 test_60i() {
8543         changelog_register || error "changelog_register failed"
8544         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8545         changelog_users $SINGLEMDS | grep -q $cl_user ||
8546                 error "User $cl_user not found in changelog_users"
8547         changelog_chmask "ALL"
8548         t60i_load &
8549         local PID=$!
8550         for((i=0; i<100; i++)); do
8551                 changelog_dump >/dev/null ||
8552                         error "can't read changelog"
8553         done
8554         kill $PID
8555         wait $PID
8556         changelog_deregister || error "changelog_deregister failed"
8557         $LCTL set_param fail_loc=0
8558 }
8559 run_test 60i "llog: new record vs reader race"
8560
8561 test_61a() {
8562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8563
8564         f="$DIR/f61"
8565         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8566         cancel_lru_locks osc
8567         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8568         sync
8569 }
8570 run_test 61a "mmap() writes don't make sync hang ================"
8571
8572 test_61b() {
8573         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8574 }
8575 run_test 61b "mmap() of unstriped file is successful"
8576
8577 # bug 2330 - insufficient obd_match error checking causes LBUG
8578 test_62() {
8579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8580
8581         f="$DIR/f62"
8582         echo foo > $f
8583         cancel_lru_locks osc
8584         lctl set_param fail_loc=0x405
8585         cat $f && error "cat succeeded, expect -EIO"
8586         lctl set_param fail_loc=0
8587 }
8588 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8589 # match every page all of the time.
8590 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8591
8592 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8593 # Though this test is irrelevant anymore, it helped to reveal some
8594 # other grant bugs (LU-4482), let's keep it.
8595 test_63a() {   # was test_63
8596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8597
8598         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8599
8600         for i in `seq 10` ; do
8601                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8602                 sleep 5
8603                 kill $!
8604                 sleep 1
8605         done
8606
8607         rm -f $DIR/f63 || true
8608 }
8609 run_test 63a "Verify oig_wait interruption does not crash ======="
8610
8611 # bug 2248 - async write errors didn't return to application on sync
8612 # bug 3677 - async write errors left page locked
8613 test_63b() {
8614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8615
8616         debugsave
8617         lctl set_param debug=-1
8618
8619         # ensure we have a grant to do async writes
8620         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8621         rm $DIR/$tfile
8622
8623         sync    # sync lest earlier test intercept the fail_loc
8624
8625         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8626         lctl set_param fail_loc=0x80000406
8627         $MULTIOP $DIR/$tfile Owy && \
8628                 error "sync didn't return ENOMEM"
8629         sync; sleep 2; sync     # do a real sync this time to flush page
8630         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8631                 error "locked page left in cache after async error" || true
8632         debugrestore
8633 }
8634 run_test 63b "async write errors should be returned to fsync ==="
8635
8636 test_64a () {
8637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8638
8639         lfs df $DIR
8640         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8641 }
8642 run_test 64a "verify filter grant calculations (in kernel) ====="
8643
8644 test_64b () {
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646
8647         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8648 }
8649 run_test 64b "check out-of-space detection on client"
8650
8651 test_64c() {
8652         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8653 }
8654 run_test 64c "verify grant shrink"
8655
8656 import_param() {
8657         local tgt=$1
8658         local param=$2
8659
8660         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8661 }
8662
8663 # this does exactly what osc_request.c:osc_announce_cached() does in
8664 # order to calculate max amount of grants to ask from server
8665 want_grant() {
8666         local tgt=$1
8667
8668         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8669         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8670
8671         ((rpc_in_flight++));
8672         nrpages=$((nrpages * rpc_in_flight))
8673
8674         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8675
8676         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8677
8678         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8679         local undirty=$((nrpages * PAGE_SIZE))
8680
8681         local max_extent_pages
8682         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8683         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8684         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8685         local grant_extent_tax
8686         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8687
8688         undirty=$((undirty + nrextents * grant_extent_tax))
8689
8690         echo $undirty
8691 }
8692
8693 # this is size of unit for grant allocation. It should be equal to
8694 # what tgt_grant.c:tgt_grant_chunk() calculates
8695 grant_chunk() {
8696         local tgt=$1
8697         local max_brw_size
8698         local grant_extent_tax
8699
8700         max_brw_size=$(import_param $tgt max_brw_size)
8701
8702         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8703
8704         echo $(((max_brw_size + grant_extent_tax) * 2))
8705 }
8706
8707 test_64d() {
8708         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8709                 skip "OST < 2.10.55 doesn't limit grants enough"
8710
8711         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8712
8713         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8714                 skip "no grant_param connect flag"
8715
8716         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8717
8718         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8719         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8720
8721
8722         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8723         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8724
8725         $LFS setstripe $DIR/$tfile -i 0 -c 1
8726         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8727         ddpid=$!
8728
8729         while kill -0 $ddpid; do
8730                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8731
8732                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8733                         kill $ddpid
8734                         error "cur_grant $cur_grant > $max_cur_granted"
8735                 fi
8736
8737                 sleep 1
8738         done
8739 }
8740 run_test 64d "check grant limit exceed"
8741
8742 check_grants() {
8743         local tgt=$1
8744         local expected=$2
8745         local msg=$3
8746         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8747
8748         ((cur_grants == expected)) ||
8749                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8750 }
8751
8752 round_up_p2() {
8753         echo $((($1 + $2 - 1) & ~($2 - 1)))
8754 }
8755
8756 test_64e() {
8757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8758         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8759                 skip "Need OSS version at least 2.11.56"
8760
8761         # Remount client to reset grant
8762         remount_client $MOUNT || error "failed to remount client"
8763         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8764
8765         local init_grants=$(import_param $osc_tgt initial_grant)
8766
8767         check_grants $osc_tgt $init_grants "init grants"
8768
8769         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8770         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8771         local gbs=$(import_param $osc_tgt grant_block_size)
8772
8773         # write random number of bytes from max_brw_size / 4 to max_brw_size
8774         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8775         # align for direct io
8776         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8777         # round to grant consumption unit
8778         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8779
8780         local grants=$((wb_round_up + extent_tax))
8781
8782         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8783
8784         # define OBD_FAIL_TGT_NO_GRANT 0x725
8785         # make the server not grant more back
8786         do_facet ost1 $LCTL set_param fail_loc=0x725
8787         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8788
8789         do_facet ost1 $LCTL set_param fail_loc=0
8790
8791         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8792
8793         rm -f $DIR/$tfile || error "rm failed"
8794
8795         # Remount client to reset grant
8796         remount_client $MOUNT || error "failed to remount client"
8797         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8798
8799         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8800
8801         # define OBD_FAIL_TGT_NO_GRANT 0x725
8802         # make the server not grant more back
8803         do_facet ost1 $LCTL set_param fail_loc=0x725
8804         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8805         do_facet ost1 $LCTL set_param fail_loc=0
8806
8807         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8808 }
8809 run_test 64e "check grant consumption (no grant allocation)"
8810
8811 test_64f() {
8812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8813
8814         # Remount client to reset grant
8815         remount_client $MOUNT || error "failed to remount client"
8816         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8817
8818         local init_grants=$(import_param $osc_tgt initial_grant)
8819         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8820         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8821         local gbs=$(import_param $osc_tgt grant_block_size)
8822         local chunk=$(grant_chunk $osc_tgt)
8823
8824         # write random number of bytes from max_brw_size / 4 to max_brw_size
8825         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8826         # align for direct io
8827         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8828         # round to grant consumption unit
8829         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8830
8831         local grants=$((wb_round_up + extent_tax))
8832
8833         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8834         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8835                 error "error writing to $DIR/$tfile"
8836
8837         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8838                 "direct io with grant allocation"
8839
8840         rm -f $DIR/$tfile || error "rm failed"
8841
8842         # Remount client to reset grant
8843         remount_client $MOUNT || error "failed to remount client"
8844         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8845
8846         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8847
8848         local cmd="oO_WRONLY:w${write_bytes}_yc"
8849
8850         $MULTIOP $DIR/$tfile $cmd &
8851         MULTIPID=$!
8852         sleep 1
8853
8854         check_grants $osc_tgt $((init_grants - grants)) \
8855                 "buffered io, not write rpc"
8856
8857         kill -USR1 $MULTIPID
8858         wait
8859
8860         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8861                 "buffered io, one RPC"
8862 }
8863 run_test 64f "check grant consumption (with grant allocation)"
8864
8865 test_64g() {
8866         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8867         #       skip "Need MDS version at least 2.14.54"
8868
8869         local mdts=$(comma_list $(mdts_nodes))
8870
8871         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8872                         tr '\n' ' ')
8873         stack_trap "$LCTL set_param $old"
8874
8875         # generate dirty pages and increase dirty granted on MDT
8876         stack_trap "rm -f $DIR/$tfile-*"
8877         for (( i = 0; i < 10; i++)); do
8878                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8879                         error "can't set stripe"
8880                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8881                         error "can't dd"
8882                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8883                         $LFS getstripe $DIR/$tfile-$i
8884                         error "not DoM file"
8885                 }
8886         done
8887
8888         # flush dirty pages
8889         sync
8890
8891         # wait until grant shrink reset grant dirty on MDTs
8892         for ((i = 0; i < 120; i++)); do
8893                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8894                         awk '{sum=sum+$1} END {print sum}')
8895                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8896                 echo "$grant_dirty grants, $vm_dirty pages"
8897                 (( grant_dirty + vm_dirty == 0 )) && break
8898                 (( i == 3 )) && sync &&
8899                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8900                 sleep 1
8901         done
8902
8903         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8904                 awk '{sum=sum+$1} END {print sum}')
8905         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8906 }
8907 run_test 64g "grant shrink on MDT"
8908
8909 test_64h() {
8910         local instance=$($LFS getname -i $DIR)
8911         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8912         local num_exps=$(do_facet ost1 \
8913             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8914         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8915         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8916         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8917
8918         # 10MiB is for file to be written, max_brw_size * 16 *
8919         # num_exps is space reserve so that tgt_grant_shrink() decided
8920         # to not shrink
8921         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8922         (( avail * 1024 < expect )) &&
8923                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8924
8925         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8926         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8927         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8928         $LCTL set_param osc.*OST0000*.grant_shrink=1
8929         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8930
8931         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8932         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8933
8934         # drop cache so that coming read would do rpc
8935         cancel_lru_locks osc
8936
8937         # shrink interval is set to 10, pause for 7 seconds so that
8938         # grant thread did not wake up yet but coming read entered
8939         # shrink mode for rpc (osc_should_shrink_grant())
8940         sleep 7
8941
8942         declare -a cur_grant_bytes
8943         declare -a tot_granted
8944         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8945         tot_granted[0]=$(do_facet ost1 \
8946             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8947
8948         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8949
8950         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8951         tot_granted[1]=$(do_facet ost1 \
8952             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8953
8954         # grant change should be equal on both sides
8955         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8956                 tot_granted[0] - tot_granted[1])) ||
8957                 error "grant change mismatch, "                                \
8958                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8959                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8960 }
8961 run_test 64h "grant shrink on read"
8962
8963 test_64i() {
8964         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8965                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8966
8967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8968         remote_ost_nodsh && skip "remote OSTs with nodsh"
8969
8970         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8971
8972         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8973
8974         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8975         local instance=$($LFS getname -i $DIR)
8976
8977         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8978         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8979
8980         # shrink grants and simulate rpc loss
8981         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8982         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8983         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8984
8985         fail ost1
8986
8987         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8988
8989         local testid=$(echo $TESTNAME | tr '_' ' ')
8990
8991         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8992                 grep "GRANT, real grant" &&
8993                 error "client has more grants then it owns" || true
8994 }
8995 run_test 64i "shrink on reconnect"
8996
8997 # bug 1414 - set/get directories' stripe info
8998 test_65a() {
8999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9000
9001         test_mkdir $DIR/$tdir
9002         touch $DIR/$tdir/f1
9003         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9004 }
9005 run_test 65a "directory with no stripe info"
9006
9007 test_65b() {
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009
9010         test_mkdir $DIR/$tdir
9011         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9012
9013         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9014                                                 error "setstripe"
9015         touch $DIR/$tdir/f2
9016         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9017 }
9018 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9019
9020 test_65c() {
9021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9022         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9023
9024         test_mkdir $DIR/$tdir
9025         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9026
9027         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9028                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9029         touch $DIR/$tdir/f3
9030         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9031 }
9032 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9033
9034 test_65d() {
9035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9036
9037         test_mkdir $DIR/$tdir
9038         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9039         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9040
9041         if [[ $STRIPECOUNT -le 0 ]]; then
9042                 sc=1
9043         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9044                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9045                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9046         else
9047                 sc=$(($STRIPECOUNT - 1))
9048         fi
9049         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9050         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9051         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9052                 error "lverify failed"
9053 }
9054 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9055
9056 test_65e() {
9057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9058
9059         test_mkdir $DIR/$tdir
9060
9061         $LFS setstripe $DIR/$tdir || error "setstripe"
9062         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9063                                         error "no stripe info failed"
9064         touch $DIR/$tdir/f6
9065         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9066 }
9067 run_test 65e "directory setstripe defaults"
9068
9069 test_65f() {
9070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9071
9072         test_mkdir $DIR/${tdir}f
9073         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9074                 error "setstripe succeeded" || true
9075 }
9076 run_test 65f "dir setstripe permission (should return error) ==="
9077
9078 test_65g() {
9079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9080
9081         test_mkdir $DIR/$tdir
9082         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9083
9084         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9085                 error "setstripe -S failed"
9086         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9087         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9088                 error "delete default stripe failed"
9089 }
9090 run_test 65g "directory setstripe -d"
9091
9092 test_65h() {
9093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9094
9095         test_mkdir $DIR/$tdir
9096         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9097
9098         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9099                 error "setstripe -S failed"
9100         test_mkdir $DIR/$tdir/dd1
9101         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9102                 error "stripe info inherit failed"
9103 }
9104 run_test 65h "directory stripe info inherit ===================="
9105
9106 test_65i() {
9107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9108
9109         save_layout_restore_at_exit $MOUNT
9110
9111         # bug6367: set non-default striping on root directory
9112         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9113
9114         # bug12836: getstripe on -1 default directory striping
9115         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9116
9117         # bug12836: getstripe -v on -1 default directory striping
9118         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9119
9120         # bug12836: new find on -1 default directory striping
9121         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9122 }
9123 run_test 65i "various tests to set root directory striping"
9124
9125 test_65j() { # bug6367
9126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9127
9128         sync; sleep 1
9129
9130         # if we aren't already remounting for each test, do so for this test
9131         if [ "$I_MOUNTED" = "yes" ]; then
9132                 cleanup || error "failed to unmount"
9133                 setup
9134         fi
9135
9136         save_layout_restore_at_exit $MOUNT
9137
9138         $LFS setstripe -d $MOUNT || error "setstripe failed"
9139 }
9140 run_test 65j "set default striping on root directory (bug 6367)="
9141
9142 cleanup_65k() {
9143         rm -rf $DIR/$tdir
9144         wait_delete_completed
9145         do_facet $SINGLEMDS "lctl set_param -n \
9146                 osp.$ost*MDT0000.max_create_count=$max_count"
9147         do_facet $SINGLEMDS "lctl set_param -n \
9148                 osp.$ost*MDT0000.create_count=$count"
9149         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9150         echo $INACTIVE_OSC "is Activate"
9151
9152         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9153 }
9154
9155 test_65k() { # bug11679
9156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9157         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9158         remote_mds_nodsh && skip "remote MDS with nodsh"
9159
9160         local disable_precreate=true
9161         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9162                 disable_precreate=false
9163
9164         echo "Check OST status: "
9165         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9166                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9167
9168         for OSC in $MDS_OSCS; do
9169                 echo $OSC "is active"
9170                 do_facet $SINGLEMDS lctl --device %$OSC activate
9171         done
9172
9173         for INACTIVE_OSC in $MDS_OSCS; do
9174                 local ost=$(osc_to_ost $INACTIVE_OSC)
9175                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9176                                lov.*md*.target_obd |
9177                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9178
9179                 mkdir -p $DIR/$tdir
9180                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9181                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9182
9183                 echo "Deactivate: " $INACTIVE_OSC
9184                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9185
9186                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9187                               osp.$ost*MDT0000.create_count")
9188                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9189                                   osp.$ost*MDT0000.max_create_count")
9190                 $disable_precreate &&
9191                         do_facet $SINGLEMDS "lctl set_param -n \
9192                                 osp.$ost*MDT0000.max_create_count=0"
9193
9194                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9195                         [ -f $DIR/$tdir/$idx ] && continue
9196                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9197                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9198                                 { cleanup_65k;
9199                                   error "setstripe $idx should succeed"; }
9200                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9201                 done
9202                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9203                 rmdir $DIR/$tdir
9204
9205                 do_facet $SINGLEMDS "lctl set_param -n \
9206                         osp.$ost*MDT0000.max_create_count=$max_count"
9207                 do_facet $SINGLEMDS "lctl set_param -n \
9208                         osp.$ost*MDT0000.create_count=$count"
9209                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9210                 echo $INACTIVE_OSC "is Activate"
9211
9212                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9213         done
9214 }
9215 run_test 65k "validate manual striping works properly with deactivated OSCs"
9216
9217 test_65l() { # bug 12836
9218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9219
9220         test_mkdir -p $DIR/$tdir/test_dir
9221         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9222         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9223 }
9224 run_test 65l "lfs find on -1 stripe dir ========================"
9225
9226 test_65m() {
9227         local layout=$(save_layout $MOUNT)
9228         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9229                 restore_layout $MOUNT $layout
9230                 error "setstripe should fail by non-root users"
9231         }
9232         true
9233 }
9234 run_test 65m "normal user can't set filesystem default stripe"
9235
9236 test_65n() {
9237         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9238         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9239                 skip "Need MDS version at least 2.12.50"
9240         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9241
9242         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9243         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9244         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9245
9246         save_layout_restore_at_exit $MOUNT
9247
9248         # new subdirectory under root directory should not inherit
9249         # the default layout from root
9250         local dir1=$MOUNT/$tdir-1
9251         mkdir $dir1 || error "mkdir $dir1 failed"
9252         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9253                 error "$dir1 shouldn't have LOV EA"
9254
9255         # delete the default layout on root directory
9256         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9257
9258         local dir2=$MOUNT/$tdir-2
9259         mkdir $dir2 || error "mkdir $dir2 failed"
9260         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9261                 error "$dir2 shouldn't have LOV EA"
9262
9263         # set a new striping pattern on root directory
9264         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9265         local new_def_stripe_size=$((def_stripe_size * 2))
9266         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9267                 error "set stripe size on $MOUNT failed"
9268
9269         # new file created in $dir2 should inherit the new stripe size from
9270         # the filesystem default
9271         local file2=$dir2/$tfile-2
9272         touch $file2 || error "touch $file2 failed"
9273
9274         local file2_stripe_size=$($LFS getstripe -S $file2)
9275         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9276         {
9277                 echo "file2_stripe_size: '$file2_stripe_size'"
9278                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9279                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9280         }
9281
9282         local dir3=$MOUNT/$tdir-3
9283         mkdir $dir3 || error "mkdir $dir3 failed"
9284         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9285         # the root layout, which is the actual default layout that will be used
9286         # when new files are created in $dir3.
9287         local dir3_layout=$(get_layout_param $dir3)
9288         local root_dir_layout=$(get_layout_param $MOUNT)
9289         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9290         {
9291                 echo "dir3_layout: '$dir3_layout'"
9292                 echo "root_dir_layout: '$root_dir_layout'"
9293                 error "$dir3 should show the default layout from $MOUNT"
9294         }
9295
9296         # set OST pool on root directory
9297         local pool=$TESTNAME
9298         pool_add $pool || error "add $pool failed"
9299         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9300                 error "add targets to $pool failed"
9301
9302         $LFS setstripe -p $pool $MOUNT ||
9303                 error "set OST pool on $MOUNT failed"
9304
9305         # new file created in $dir3 should inherit the pool from
9306         # the filesystem default
9307         local file3=$dir3/$tfile-3
9308         touch $file3 || error "touch $file3 failed"
9309
9310         local file3_pool=$($LFS getstripe -p $file3)
9311         [[ "$file3_pool" = "$pool" ]] ||
9312                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9313
9314         local dir4=$MOUNT/$tdir-4
9315         mkdir $dir4 || error "mkdir $dir4 failed"
9316         local dir4_layout=$(get_layout_param $dir4)
9317         root_dir_layout=$(get_layout_param $MOUNT)
9318         echo "$LFS getstripe -d $dir4"
9319         $LFS getstripe -d $dir4
9320         echo "$LFS getstripe -d $MOUNT"
9321         $LFS getstripe -d $MOUNT
9322         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9323         {
9324                 echo "dir4_layout: '$dir4_layout'"
9325                 echo "root_dir_layout: '$root_dir_layout'"
9326                 error "$dir4 should show the default layout from $MOUNT"
9327         }
9328
9329         # new file created in $dir4 should inherit the pool from
9330         # the filesystem default
9331         local file4=$dir4/$tfile-4
9332         touch $file4 || error "touch $file4 failed"
9333
9334         local file4_pool=$($LFS getstripe -p $file4)
9335         [[ "$file4_pool" = "$pool" ]] ||
9336                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9337
9338         # new subdirectory under non-root directory should inherit
9339         # the default layout from its parent directory
9340         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9341                 error "set directory layout on $dir4 failed"
9342
9343         local dir5=$dir4/$tdir-5
9344         mkdir $dir5 || error "mkdir $dir5 failed"
9345
9346         dir4_layout=$(get_layout_param $dir4)
9347         local dir5_layout=$(get_layout_param $dir5)
9348         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9349         {
9350                 echo "dir4_layout: '$dir4_layout'"
9351                 echo "dir5_layout: '$dir5_layout'"
9352                 error "$dir5 should inherit the default layout from $dir4"
9353         }
9354
9355         # though subdir under ROOT doesn't inherit default layout, but
9356         # its sub dir/file should be created with default layout.
9357         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9358         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9359                 skip "Need MDS version at least 2.12.59"
9360
9361         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9362         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9363         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9364
9365         if [ $default_lmv_hash == "none" ]; then
9366                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9367         else
9368                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9369                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9370         fi
9371
9372         $LFS setdirstripe -D -c 2 $MOUNT ||
9373                 error "setdirstripe -D -c 2 failed"
9374         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9375         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9376         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9377 }
9378 run_test 65n "don't inherit default layout from root for new subdirectories"
9379
9380 # bug 2543 - update blocks count on client
9381 test_66() {
9382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9383
9384         COUNT=${COUNT:-8}
9385         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9386         sync; sync_all_data; sync; sync_all_data
9387         cancel_lru_locks osc
9388         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9389         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9390 }
9391 run_test 66 "update inode blocks count on client ==============="
9392
9393 meminfo() {
9394         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9395 }
9396
9397 swap_used() {
9398         swapon -s | awk '($1 == "'$1'") { print $4 }'
9399 }
9400
9401 # bug5265, obdfilter oa2dentry return -ENOENT
9402 # #define OBD_FAIL_SRV_ENOENT 0x217
9403 test_69() {
9404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9405         remote_ost_nodsh && skip "remote OST with nodsh"
9406
9407         f="$DIR/$tfile"
9408         $LFS setstripe -c 1 -i 0 $f
9409
9410         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9411
9412         do_facet ost1 lctl set_param fail_loc=0x217
9413         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9414         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9415
9416         do_facet ost1 lctl set_param fail_loc=0
9417         $DIRECTIO write $f 0 2 || error "write error"
9418
9419         cancel_lru_locks osc
9420         $DIRECTIO read $f 0 1 || error "read error"
9421
9422         do_facet ost1 lctl set_param fail_loc=0x217
9423         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9424
9425         do_facet ost1 lctl set_param fail_loc=0
9426         rm -f $f
9427 }
9428 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9429
9430 test_71() {
9431         test_mkdir $DIR/$tdir
9432         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9433         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9434 }
9435 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9436
9437 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9439         [ "$RUNAS_ID" = "$UID" ] &&
9440                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9441         # Check that testing environment is properly set up. Skip if not
9442         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9443                 skip_env "User $RUNAS_ID does not exist - skipping"
9444
9445         touch $DIR/$tfile
9446         chmod 777 $DIR/$tfile
9447         chmod ug+s $DIR/$tfile
9448         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9449                 error "$RUNAS dd $DIR/$tfile failed"
9450         # See if we are still setuid/sgid
9451         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9452                 error "S/gid is not dropped on write"
9453         # Now test that MDS is updated too
9454         cancel_lru_locks mdc
9455         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9456                 error "S/gid is not dropped on MDS"
9457         rm -f $DIR/$tfile
9458 }
9459 run_test 72a "Test that remove suid works properly (bug5695) ===="
9460
9461 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9462         local perm
9463
9464         [ "$RUNAS_ID" = "$UID" ] &&
9465                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9466         [ "$RUNAS_ID" -eq 0 ] &&
9467                 skip_env "RUNAS_ID = 0 -- skipping"
9468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9469         # Check that testing environment is properly set up. Skip if not
9470         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9471                 skip_env "User $RUNAS_ID does not exist - skipping"
9472
9473         touch $DIR/${tfile}-f{g,u}
9474         test_mkdir $DIR/${tfile}-dg
9475         test_mkdir $DIR/${tfile}-du
9476         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9477         chmod g+s $DIR/${tfile}-{f,d}g
9478         chmod u+s $DIR/${tfile}-{f,d}u
9479         for perm in 777 2777 4777; do
9480                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9481                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9482                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9483                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9484         done
9485         true
9486 }
9487 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9488
9489 # bug 3462 - multiple simultaneous MDC requests
9490 test_73() {
9491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9492
9493         test_mkdir $DIR/d73-1
9494         test_mkdir $DIR/d73-2
9495         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9496         pid1=$!
9497
9498         lctl set_param fail_loc=0x80000129
9499         $MULTIOP $DIR/d73-1/f73-2 Oc &
9500         sleep 1
9501         lctl set_param fail_loc=0
9502
9503         $MULTIOP $DIR/d73-2/f73-3 Oc &
9504         pid3=$!
9505
9506         kill -USR1 $pid1
9507         wait $pid1 || return 1
9508
9509         sleep 25
9510
9511         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9512         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9513         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9514
9515         rm -rf $DIR/d73-*
9516 }
9517 run_test 73 "multiple MDC requests (should not deadlock)"
9518
9519 test_74a() { # bug 6149, 6184
9520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9521
9522         touch $DIR/f74a
9523         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9524         #
9525         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9526         # will spin in a tight reconnection loop
9527         $LCTL set_param fail_loc=0x8000030e
9528         # get any lock that won't be difficult - lookup works.
9529         ls $DIR/f74a
9530         $LCTL set_param fail_loc=0
9531         rm -f $DIR/f74a
9532         true
9533 }
9534 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9535
9536 test_74b() { # bug 13310
9537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9538
9539         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9540         #
9541         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9542         # will spin in a tight reconnection loop
9543         $LCTL set_param fail_loc=0x8000030e
9544         # get a "difficult" lock
9545         touch $DIR/f74b
9546         $LCTL set_param fail_loc=0
9547         rm -f $DIR/f74b
9548         true
9549 }
9550 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9551
9552 test_74c() {
9553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9554
9555         #define OBD_FAIL_LDLM_NEW_LOCK
9556         $LCTL set_param fail_loc=0x319
9557         touch $DIR/$tfile && error "touch successful"
9558         $LCTL set_param fail_loc=0
9559         true
9560 }
9561 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9562
9563 slab_lic=/sys/kernel/slab/lustre_inode_cache
9564 num_objects() {
9565         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9566         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9567                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9568 }
9569
9570 test_76a() { # Now for b=20433, added originally in b=1443
9571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9572
9573         cancel_lru_locks osc
9574         # there may be some slab objects cached per core
9575         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9576         local before=$(num_objects)
9577         local count=$((512 * cpus))
9578         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9579         local margin=$((count / 10))
9580         if [[ -f $slab_lic/aliases ]]; then
9581                 local aliases=$(cat $slab_lic/aliases)
9582                 (( aliases > 0 )) && margin=$((margin * aliases))
9583         fi
9584
9585         echo "before slab objects: $before"
9586         for i in $(seq $count); do
9587                 touch $DIR/$tfile
9588                 rm -f $DIR/$tfile
9589         done
9590         cancel_lru_locks osc
9591         local after=$(num_objects)
9592         echo "created: $count, after slab objects: $after"
9593         # shared slab counts are not very accurate, allow significant margin
9594         # the main goal is that the cache growth is not permanently > $count
9595         while (( after > before + margin )); do
9596                 sleep 1
9597                 after=$(num_objects)
9598                 wait=$((wait + 1))
9599                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9600                 if (( wait > 60 )); then
9601                         error "inode slab grew from $before+$margin to $after"
9602                 fi
9603         done
9604 }
9605 run_test 76a "confirm clients recycle inodes properly ===="
9606
9607 test_76b() {
9608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9609         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9610
9611         local count=512
9612         local before=$(num_objects)
9613
9614         for i in $(seq $count); do
9615                 mkdir $DIR/$tdir
9616                 rmdir $DIR/$tdir
9617         done
9618
9619         local after=$(num_objects)
9620         local wait=0
9621
9622         while (( after > before )); do
9623                 sleep 1
9624                 after=$(num_objects)
9625                 wait=$((wait + 1))
9626                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9627                 if (( wait > 60 )); then
9628                         error "inode slab grew from $before to $after"
9629                 fi
9630         done
9631
9632         echo "slab objects before: $before, after: $after"
9633 }
9634 run_test 76b "confirm clients recycle directory inodes properly ===="
9635
9636 export ORIG_CSUM=""
9637 set_checksums()
9638 {
9639         # Note: in sptlrpc modes which enable its own bulk checksum, the
9640         # original crc32_le bulk checksum will be automatically disabled,
9641         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9642         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9643         # In this case set_checksums() will not be no-op, because sptlrpc
9644         # bulk checksum will be enabled all through the test.
9645
9646         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9647         lctl set_param -n osc.*.checksums $1
9648         return 0
9649 }
9650
9651 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9652                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9653 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9654                              tr -d [] | head -n1)}
9655 set_checksum_type()
9656 {
9657         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9658         rc=$?
9659         log "set checksum type to $1, rc = $rc"
9660         return $rc
9661 }
9662
9663 get_osc_checksum_type()
9664 {
9665         # arugment 1: OST name, like OST0000
9666         ost=$1
9667         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9668                         sed 's/.*\[\(.*\)\].*/\1/g')
9669         rc=$?
9670         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9671         echo $checksum_type
9672 }
9673
9674 F77_TMP=$TMP/f77-temp
9675 F77SZ=8
9676 setup_f77() {
9677         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9678                 error "error writing to $F77_TMP"
9679 }
9680
9681 test_77a() { # bug 10889
9682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9683         $GSS && skip_env "could not run with gss"
9684
9685         [ ! -f $F77_TMP ] && setup_f77
9686         set_checksums 1
9687         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9688         set_checksums 0
9689         rm -f $DIR/$tfile
9690 }
9691 run_test 77a "normal checksum read/write operation"
9692
9693 test_77b() { # bug 10889
9694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9695         $GSS && skip_env "could not run with gss"
9696
9697         [ ! -f $F77_TMP ] && setup_f77
9698         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9699         $LCTL set_param fail_loc=0x80000409
9700         set_checksums 1
9701
9702         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9703                 error "dd error: $?"
9704         $LCTL set_param fail_loc=0
9705
9706         for algo in $CKSUM_TYPES; do
9707                 cancel_lru_locks osc
9708                 set_checksum_type $algo
9709                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9710                 $LCTL set_param fail_loc=0x80000408
9711                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9712                 $LCTL set_param fail_loc=0
9713         done
9714         set_checksums 0
9715         set_checksum_type $ORIG_CSUM_TYPE
9716         rm -f $DIR/$tfile
9717 }
9718 run_test 77b "checksum error on client write, read"
9719
9720 cleanup_77c() {
9721         trap 0
9722         set_checksums 0
9723         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9724         $check_ost &&
9725                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9726         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9727         $check_ost && [ -n "$ost_file_prefix" ] &&
9728                 do_facet ost1 rm -f ${ost_file_prefix}\*
9729 }
9730
9731 test_77c() {
9732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9733         $GSS && skip_env "could not run with gss"
9734         remote_ost_nodsh && skip "remote OST with nodsh"
9735
9736         local bad1
9737         local osc_file_prefix
9738         local osc_file
9739         local check_ost=false
9740         local ost_file_prefix
9741         local ost_file
9742         local orig_cksum
9743         local dump_cksum
9744         local fid
9745
9746         # ensure corruption will occur on first OSS/OST
9747         $LFS setstripe -i 0 $DIR/$tfile
9748
9749         [ ! -f $F77_TMP ] && setup_f77
9750         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9751                 error "dd write error: $?"
9752         fid=$($LFS path2fid $DIR/$tfile)
9753
9754         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9755         then
9756                 check_ost=true
9757                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9758                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9759         else
9760                 echo "OSS do not support bulk pages dump upon error"
9761         fi
9762
9763         osc_file_prefix=$($LCTL get_param -n debug_path)
9764         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9765
9766         trap cleanup_77c EXIT
9767
9768         set_checksums 1
9769         # enable bulk pages dump upon error on Client
9770         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9771         # enable bulk pages dump upon error on OSS
9772         $check_ost &&
9773                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9774
9775         # flush Client cache to allow next read to reach OSS
9776         cancel_lru_locks osc
9777
9778         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9779         $LCTL set_param fail_loc=0x80000408
9780         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9781         $LCTL set_param fail_loc=0
9782
9783         rm -f $DIR/$tfile
9784
9785         # check cksum dump on Client
9786         osc_file=$(ls ${osc_file_prefix}*)
9787         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9788         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9789         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9790         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9791         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9792                      cksum)
9793         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9794         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9795                 error "dump content does not match on Client"
9796
9797         $check_ost || skip "No need to check cksum dump on OSS"
9798
9799         # check cksum dump on OSS
9800         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9801         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9802         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9803         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9804         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9805                 error "dump content does not match on OSS"
9806
9807         cleanup_77c
9808 }
9809 run_test 77c "checksum error on client read with debug"
9810
9811 test_77d() { # bug 10889
9812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9813         $GSS && skip_env "could not run with gss"
9814
9815         stack_trap "rm -f $DIR/$tfile"
9816         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9817         $LCTL set_param fail_loc=0x80000409
9818         set_checksums 1
9819         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9820                 error "direct write: rc=$?"
9821         $LCTL set_param fail_loc=0
9822         set_checksums 0
9823
9824         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9825         $LCTL set_param fail_loc=0x80000408
9826         set_checksums 1
9827         cancel_lru_locks osc
9828         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9829                 error "direct read: rc=$?"
9830         $LCTL set_param fail_loc=0
9831         set_checksums 0
9832 }
9833 run_test 77d "checksum error on OST direct write, read"
9834
9835 test_77f() { # bug 10889
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837         $GSS && skip_env "could not run with gss"
9838
9839         set_checksums 1
9840         stack_trap "rm -f $DIR/$tfile"
9841         for algo in $CKSUM_TYPES; do
9842                 cancel_lru_locks osc
9843                 set_checksum_type $algo
9844                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9845                 $LCTL set_param fail_loc=0x409
9846                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9847                         error "direct write succeeded"
9848                 $LCTL set_param fail_loc=0
9849         done
9850         set_checksum_type $ORIG_CSUM_TYPE
9851         set_checksums 0
9852 }
9853 run_test 77f "repeat checksum error on write (expect error)"
9854
9855 test_77g() { # bug 10889
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857         $GSS && skip_env "could not run with gss"
9858         remote_ost_nodsh && skip "remote OST with nodsh"
9859
9860         [ ! -f $F77_TMP ] && setup_f77
9861
9862         local file=$DIR/$tfile
9863         stack_trap "rm -f $file" EXIT
9864
9865         $LFS setstripe -c 1 -i 0 $file
9866         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9867         do_facet ost1 lctl set_param fail_loc=0x8000021a
9868         set_checksums 1
9869         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9870                 error "write error: rc=$?"
9871         do_facet ost1 lctl set_param fail_loc=0
9872         set_checksums 0
9873
9874         cancel_lru_locks osc
9875         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9876         do_facet ost1 lctl set_param fail_loc=0x8000021b
9877         set_checksums 1
9878         cmp $F77_TMP $file || error "file compare failed"
9879         do_facet ost1 lctl set_param fail_loc=0
9880         set_checksums 0
9881 }
9882 run_test 77g "checksum error on OST write, read"
9883
9884 test_77k() { # LU-10906
9885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9886         $GSS && skip_env "could not run with gss"
9887
9888         local cksum_param="osc.$FSNAME*.checksums"
9889         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9890         local checksum
9891         local i
9892
9893         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9894         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9895         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9896
9897         for i in 0 1; do
9898                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9899                         error "failed to set checksum=$i on MGS"
9900                 wait_update $HOSTNAME "$get_checksum" $i
9901                 #remount
9902                 echo "remount client, checksum should be $i"
9903                 remount_client $MOUNT || error "failed to remount client"
9904                 checksum=$(eval $get_checksum)
9905                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9906         done
9907         # remove persistent param to avoid races with checksum mountopt below
9908         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9909                 error "failed to delete checksum on MGS"
9910
9911         for opt in "checksum" "nochecksum"; do
9912                 #remount with mount option
9913                 echo "remount client with option $opt, checksum should be $i"
9914                 umount_client $MOUNT || error "failed to umount client"
9915                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9916                         error "failed to mount client with option '$opt'"
9917                 checksum=$(eval $get_checksum)
9918                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9919                 i=$((i - 1))
9920         done
9921
9922         remount_client $MOUNT || error "failed to remount client"
9923 }
9924 run_test 77k "enable/disable checksum correctly"
9925
9926 test_77l() {
9927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9928         $GSS && skip_env "could not run with gss"
9929
9930         set_checksums 1
9931         stack_trap "set_checksums $ORIG_CSUM" EXIT
9932         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9933
9934         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9935
9936         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9937         for algo in $CKSUM_TYPES; do
9938                 set_checksum_type $algo || error "fail to set checksum type $algo"
9939                 osc_algo=$(get_osc_checksum_type OST0000)
9940                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9941
9942                 # no locks, no reqs to let the connection idle
9943                 cancel_lru_locks osc
9944                 lru_resize_disable osc
9945                 wait_osc_import_state client ost1 IDLE
9946
9947                 # ensure ost1 is connected
9948                 stat $DIR/$tfile >/dev/null || error "can't stat"
9949                 wait_osc_import_state client ost1 FULL
9950
9951                 osc_algo=$(get_osc_checksum_type OST0000)
9952                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9953         done
9954         return 0
9955 }
9956 run_test 77l "preferred checksum type is remembered after reconnected"
9957
9958 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9959 rm -f $F77_TMP
9960 unset F77_TMP
9961
9962 test_77m() {
9963         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9964                 skip "Need at least version 2.14.52"
9965         local param=checksum_speed
9966
9967         $LCTL get_param $param || error "reading $param failed"
9968
9969         csum_speeds=$($LCTL get_param -n $param)
9970
9971         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9972                 error "known checksum types are missing"
9973 }
9974 run_test 77m "Verify checksum_speed is correctly read"
9975
9976 check_filefrag_77n() {
9977         local nr_ext=0
9978         local starts=()
9979         local ends=()
9980
9981         while read extidx a b start end rest; do
9982                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9983                         nr_ext=$(( $nr_ext + 1 ))
9984                         starts+=( ${start%..} )
9985                         ends+=( ${end%:} )
9986                 fi
9987         done < <( filefrag -sv $1 )
9988
9989         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9990         return 1
9991 }
9992
9993 test_77n() {
9994         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9995
9996         touch $DIR/$tfile
9997         $TRUNCATE $DIR/$tfile 0
9998         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9999         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10000         check_filefrag_77n $DIR/$tfile ||
10001                 skip "$tfile blocks not contiguous around hole"
10002
10003         set_checksums 1
10004         stack_trap "set_checksums $ORIG_CSUM" EXIT
10005         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10006         stack_trap "rm -f $DIR/$tfile"
10007
10008         for algo in $CKSUM_TYPES; do
10009                 if [[ "$algo" =~ ^t10 ]]; then
10010                         set_checksum_type $algo ||
10011                                 error "fail to set checksum type $algo"
10012                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10013                                 error "fail to read $tfile with $algo"
10014                 fi
10015         done
10016         rm -f $DIR/$tfile
10017         return 0
10018 }
10019 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10020
10021 test_77o() {
10022         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10023                 skip "Need at least version 2.14.54"
10024         local ofd=obdfilter
10025         local mdt=mdt
10026
10027         # print OST checksum_type
10028         echo "$ofd.$FSNAME-*.checksum_type:"
10029         do_nodes $(comma_list $(osts_nodes)) \
10030                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10031
10032         # print MDT checksum_type
10033         echo "$mdt.$FSNAME-*.checksum_type:"
10034         do_nodes $(comma_list $(mdts_nodes)) \
10035                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10036
10037         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10038                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10039
10040         (( $o_count == $OSTCOUNT )) ||
10041                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10042
10043         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10044                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10045
10046         (( $m_count == $MDSCOUNT )) ||
10047                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10048 }
10049 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10050
10051 cleanup_test_78() {
10052         trap 0
10053         rm -f $DIR/$tfile
10054 }
10055
10056 test_78() { # bug 10901
10057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10058         remote_ost || skip_env "local OST"
10059
10060         NSEQ=5
10061         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10062         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10063         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10064         echo "MemTotal: $MEMTOTAL"
10065
10066         # reserve 256MB of memory for the kernel and other running processes,
10067         # and then take 1/2 of the remaining memory for the read/write buffers.
10068         if [ $MEMTOTAL -gt 512 ] ;then
10069                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10070         else
10071                 # for those poor memory-starved high-end clusters...
10072                 MEMTOTAL=$((MEMTOTAL / 2))
10073         fi
10074         echo "Mem to use for directio: $MEMTOTAL"
10075
10076         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10077         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10078         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10079         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10080                 head -n1)
10081         echo "Smallest OST: $SMALLESTOST"
10082         [[ $SMALLESTOST -lt 10240 ]] &&
10083                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10084
10085         trap cleanup_test_78 EXIT
10086
10087         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10088                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10089
10090         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10091         echo "File size: $F78SIZE"
10092         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10093         for i in $(seq 1 $NSEQ); do
10094                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10095                 echo directIO rdwr round $i of $NSEQ
10096                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10097         done
10098
10099         cleanup_test_78
10100 }
10101 run_test 78 "handle large O_DIRECT writes correctly ============"
10102
10103 test_79() { # bug 12743
10104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10105
10106         wait_delete_completed
10107
10108         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10109         BKFREE=$(calc_osc_kbytes kbytesfree)
10110         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10111
10112         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10113         DFTOTAL=`echo $STRING | cut -d, -f1`
10114         DFUSED=`echo $STRING  | cut -d, -f2`
10115         DFAVAIL=`echo $STRING | cut -d, -f3`
10116         DFFREE=$(($DFTOTAL - $DFUSED))
10117
10118         ALLOWANCE=$((64 * $OSTCOUNT))
10119
10120         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10121            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10122                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10123         fi
10124         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10125            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10126                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10127         fi
10128         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10129            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10130                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10131         fi
10132 }
10133 run_test 79 "df report consistency check ======================="
10134
10135 test_80() { # bug 10718
10136         remote_ost_nodsh && skip "remote OST with nodsh"
10137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10138
10139         # relax strong synchronous semantics for slow backends like ZFS
10140         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10141                 local soc="obdfilter.*.sync_lock_cancel"
10142                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10143
10144                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10145                 if [ -z "$save" ]; then
10146                         soc="obdfilter.*.sync_on_lock_cancel"
10147                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10148                 fi
10149
10150                 if [ "$save" != "never" ]; then
10151                         local hosts=$(comma_list $(osts_nodes))
10152
10153                         do_nodes $hosts $LCTL set_param $soc=never
10154                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10155                 fi
10156         fi
10157
10158         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10159         sync; sleep 1; sync
10160         local before=$(date +%s)
10161         cancel_lru_locks osc
10162         local after=$(date +%s)
10163         local diff=$((after - before))
10164         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10165
10166         rm -f $DIR/$tfile
10167 }
10168 run_test 80 "Page eviction is equally fast at high offsets too"
10169
10170 test_81a() { # LU-456
10171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10172         remote_ost_nodsh && skip "remote OST with nodsh"
10173
10174         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10175         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10176         do_facet ost1 lctl set_param fail_loc=0x80000228
10177
10178         # write should trigger a retry and success
10179         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10180         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10181         RC=$?
10182         if [ $RC -ne 0 ] ; then
10183                 error "write should success, but failed for $RC"
10184         fi
10185 }
10186 run_test 81a "OST should retry write when get -ENOSPC ==============="
10187
10188 test_81b() { # LU-456
10189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10190         remote_ost_nodsh && skip "remote OST with nodsh"
10191
10192         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10193         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10194         do_facet ost1 lctl set_param fail_loc=0x228
10195
10196         # write should retry several times and return -ENOSPC finally
10197         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10198         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10199         RC=$?
10200         ENOSPC=28
10201         if [ $RC -ne $ENOSPC ] ; then
10202                 error "dd should fail for -ENOSPC, but succeed."
10203         fi
10204 }
10205 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10206
10207 test_99() {
10208         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10209
10210         test_mkdir $DIR/$tdir.cvsroot
10211         chown $RUNAS_ID $DIR/$tdir.cvsroot
10212
10213         cd $TMP
10214         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10215
10216         cd /etc/init.d
10217         # some versions of cvs import exit(1) when asked to import links or
10218         # files they can't read.  ignore those files.
10219         local toignore=$(find . -type l -printf '-I %f\n' -o \
10220                          ! -perm /4 -printf '-I %f\n')
10221         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10222                 $tdir.reposname vtag rtag
10223
10224         cd $DIR
10225         test_mkdir $DIR/$tdir.reposname
10226         chown $RUNAS_ID $DIR/$tdir.reposname
10227         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10228
10229         cd $DIR/$tdir.reposname
10230         $RUNAS touch foo99
10231         $RUNAS cvs add -m 'addmsg' foo99
10232         $RUNAS cvs update
10233         $RUNAS cvs commit -m 'nomsg' foo99
10234         rm -fr $DIR/$tdir.cvsroot
10235 }
10236 run_test 99 "cvs strange file/directory operations"
10237
10238 test_100() {
10239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10240         [[ "$NETTYPE" =~ tcp ]] ||
10241                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10242         remote_ost_nodsh && skip "remote OST with nodsh"
10243         remote_mds_nodsh && skip "remote MDS with nodsh"
10244         remote_servers ||
10245                 skip "useless for local single node setup"
10246
10247         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10248                 [ "$PROT" != "tcp" ] && continue
10249                 RPORT=$(echo $REMOTE | cut -d: -f2)
10250                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10251
10252                 rc=0
10253                 LPORT=`echo $LOCAL | cut -d: -f2`
10254                 if [ $LPORT -ge 1024 ]; then
10255                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10256                         netstat -tna
10257                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10258                 fi
10259         done
10260         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10261 }
10262 run_test 100 "check local port using privileged port ==========="
10263
10264 function get_named_value()
10265 {
10266     local tag=$1
10267
10268     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10269 }
10270
10271 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10272                    awk '/^max_cached_mb/ { print $2 }')
10273
10274 cleanup_101a() {
10275         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10276         trap 0
10277 }
10278
10279 test_101a() {
10280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10281
10282         local s
10283         local discard
10284         local nreads=10000
10285         local cache_limit=32
10286
10287         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10288         trap cleanup_101a EXIT
10289         $LCTL set_param -n llite.*.read_ahead_stats=0
10290         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10291
10292         #
10293         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10294         #
10295         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10296         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10297
10298         discard=0
10299         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10300                    get_named_value 'read.but.discarded'); do
10301                         discard=$(($discard + $s))
10302         done
10303         cleanup_101a
10304
10305         $LCTL get_param osc.*-osc*.rpc_stats
10306         $LCTL get_param llite.*.read_ahead_stats
10307
10308         # Discard is generally zero, but sometimes a few random reads line up
10309         # and trigger larger readahead, which is wasted & leads to discards.
10310         if [[ $(($discard)) -gt $nreads ]]; then
10311                 error "too many ($discard) discarded pages"
10312         fi
10313         rm -f $DIR/$tfile || true
10314 }
10315 run_test 101a "check read-ahead for random reads"
10316
10317 setup_test101bc() {
10318         test_mkdir $DIR/$tdir
10319         local ssize=$1
10320         local FILE_LENGTH=$2
10321         STRIPE_OFFSET=0
10322
10323         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10324
10325         local list=$(comma_list $(osts_nodes))
10326         set_osd_param $list '' read_cache_enable 0
10327         set_osd_param $list '' writethrough_cache_enable 0
10328
10329         trap cleanup_test101bc EXIT
10330         # prepare the read-ahead file
10331         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10332
10333         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10334                                 count=$FILE_SIZE_MB 2> /dev/null
10335
10336 }
10337
10338 cleanup_test101bc() {
10339         trap 0
10340         rm -rf $DIR/$tdir
10341         rm -f $DIR/$tfile
10342
10343         local list=$(comma_list $(osts_nodes))
10344         set_osd_param $list '' read_cache_enable 1
10345         set_osd_param $list '' writethrough_cache_enable 1
10346 }
10347
10348 calc_total() {
10349         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10350 }
10351
10352 ra_check_101() {
10353         local READ_SIZE=$1
10354         local STRIPE_SIZE=$2
10355         local FILE_LENGTH=$3
10356         local RA_INC=1048576
10357         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10358         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10359                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10360         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10361                   get_named_value 'read.but.discarded' | calc_total)
10362         if [[ $DISCARD -gt $discard_limit ]]; then
10363                 $LCTL get_param llite.*.read_ahead_stats
10364                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10365         else
10366                 echo "Read-ahead success for size ${READ_SIZE}"
10367         fi
10368 }
10369
10370 test_101b() {
10371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10372         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10373
10374         local STRIPE_SIZE=1048576
10375         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10376
10377         if [ $SLOW == "yes" ]; then
10378                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10379         else
10380                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10381         fi
10382
10383         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10384
10385         # prepare the read-ahead file
10386         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10387         cancel_lru_locks osc
10388         for BIDX in 2 4 8 16 32 64 128 256
10389         do
10390                 local BSIZE=$((BIDX*4096))
10391                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10392                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10393                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10394                 $LCTL set_param -n llite.*.read_ahead_stats=0
10395                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10396                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10397                 cancel_lru_locks osc
10398                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10399         done
10400         cleanup_test101bc
10401         true
10402 }
10403 run_test 101b "check stride-io mode read-ahead ================="
10404
10405 test_101c() {
10406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10407
10408         local STRIPE_SIZE=1048576
10409         local FILE_LENGTH=$((STRIPE_SIZE*100))
10410         local nreads=10000
10411         local rsize=65536
10412         local osc_rpc_stats
10413
10414         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10415
10416         cancel_lru_locks osc
10417         $LCTL set_param osc.*.rpc_stats=0
10418         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10419         $LCTL get_param osc.*.rpc_stats
10420         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10421                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10422                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10423                 local size
10424
10425                 if [ $lines -le 20 ]; then
10426                         echo "continue debug"
10427                         continue
10428                 fi
10429                 for size in 1 2 4 8; do
10430                         local rpc=$(echo "$stats" |
10431                                     awk '($1 == "'$size':") {print $2; exit; }')
10432                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10433                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10434                 done
10435                 echo "$osc_rpc_stats check passed!"
10436         done
10437         cleanup_test101bc
10438         true
10439 }
10440 run_test 101c "check stripe_size aligned read-ahead"
10441
10442 test_101d() {
10443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10444
10445         local file=$DIR/$tfile
10446         local sz_MB=${FILESIZE_101d:-80}
10447         local ra_MB=${READAHEAD_MB:-40}
10448
10449         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10450         [ $free_MB -lt $sz_MB ] &&
10451                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10452
10453         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10454         $LFS setstripe -c -1 $file || error "setstripe failed"
10455
10456         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10457         echo Cancel LRU locks on lustre client to flush the client cache
10458         cancel_lru_locks osc
10459
10460         echo Disable read-ahead
10461         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10462         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10463         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10464         $LCTL get_param -n llite.*.max_read_ahead_mb
10465
10466         echo "Reading the test file $file with read-ahead disabled"
10467         local sz_KB=$((sz_MB * 1024 / 4))
10468         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10469         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10470         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10471                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10472
10473         echo "Cancel LRU locks on lustre client to flush the client cache"
10474         cancel_lru_locks osc
10475         echo Enable read-ahead with ${ra_MB}MB
10476         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10477
10478         echo "Reading the test file $file with read-ahead enabled"
10479         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10480                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10481
10482         echo "read-ahead disabled time read $raOFF"
10483         echo "read-ahead enabled time read $raON"
10484
10485         rm -f $file
10486         wait_delete_completed
10487
10488         # use awk for this check instead of bash because it handles decimals
10489         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10490                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10491 }
10492 run_test 101d "file read with and without read-ahead enabled"
10493
10494 test_101e() {
10495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10496
10497         local file=$DIR/$tfile
10498         local size_KB=500  #KB
10499         local count=100
10500         local bsize=1024
10501
10502         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10503         local need_KB=$((count * size_KB))
10504         [[ $free_KB -le $need_KB ]] &&
10505                 skip_env "Need free space $need_KB, have $free_KB"
10506
10507         echo "Creating $count ${size_KB}K test files"
10508         for ((i = 0; i < $count; i++)); do
10509                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10510         done
10511
10512         echo "Cancel LRU locks on lustre client to flush the client cache"
10513         cancel_lru_locks $OSC
10514
10515         echo "Reset readahead stats"
10516         $LCTL set_param -n llite.*.read_ahead_stats=0
10517
10518         for ((i = 0; i < $count; i++)); do
10519                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10520         done
10521
10522         $LCTL get_param llite.*.max_cached_mb
10523         $LCTL get_param llite.*.read_ahead_stats
10524         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10525                      get_named_value 'misses' | calc_total)
10526
10527         for ((i = 0; i < $count; i++)); do
10528                 rm -rf $file.$i 2>/dev/null
10529         done
10530
10531         #10000 means 20% reads are missing in readahead
10532         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10533 }
10534 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10535
10536 test_101f() {
10537         which iozone || skip_env "no iozone installed"
10538
10539         local old_debug=$($LCTL get_param debug)
10540         old_debug=${old_debug#*=}
10541         $LCTL set_param debug="reada mmap"
10542
10543         # create a test file
10544         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10545
10546         echo Cancel LRU locks on lustre client to flush the client cache
10547         cancel_lru_locks osc
10548
10549         echo Reset readahead stats
10550         $LCTL set_param -n llite.*.read_ahead_stats=0
10551
10552         echo mmap read the file with small block size
10553         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10554                 > /dev/null 2>&1
10555
10556         echo checking missing pages
10557         $LCTL get_param llite.*.read_ahead_stats
10558         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10559                         get_named_value 'misses' | calc_total)
10560
10561         $LCTL set_param debug="$old_debug"
10562         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10563         rm -f $DIR/$tfile
10564 }
10565 run_test 101f "check mmap read performance"
10566
10567 test_101g_brw_size_test() {
10568         local mb=$1
10569         local pages=$((mb * 1048576 / PAGE_SIZE))
10570         local file=$DIR/$tfile
10571
10572         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10573                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10574         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10575                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10576                         return 2
10577         done
10578
10579         stack_trap "rm -f $file" EXIT
10580         $LCTL set_param -n osc.*.rpc_stats=0
10581
10582         # 10 RPCs should be enough for the test
10583         local count=10
10584         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10585                 { error "dd write ${mb} MB blocks failed"; return 3; }
10586         cancel_lru_locks osc
10587         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10588                 { error "dd write ${mb} MB blocks failed"; return 4; }
10589
10590         # calculate number of full-sized read and write RPCs
10591         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10592                 sed -n '/pages per rpc/,/^$/p' |
10593                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10594                 END { print reads,writes }'))
10595         # allow one extra full-sized read RPC for async readahead
10596         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10597                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10598         [[ ${rpcs[1]} == $count ]] ||
10599                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10600 }
10601
10602 test_101g() {
10603         remote_ost_nodsh && skip "remote OST with nodsh"
10604
10605         local rpcs
10606         local osts=$(get_facets OST)
10607         local list=$(comma_list $(osts_nodes))
10608         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10609         local brw_size="obdfilter.*.brw_size"
10610
10611         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10612
10613         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10614
10615         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10616                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10617                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10618            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10619                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10620                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10621
10622                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10623                         suffix="M"
10624
10625                 if [[ $orig_mb -lt 16 ]]; then
10626                         save_lustre_params $osts "$brw_size" > $p
10627                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10628                                 error "set 16MB RPC size failed"
10629
10630                         echo "remount client to enable new RPC size"
10631                         remount_client $MOUNT || error "remount_client failed"
10632                 fi
10633
10634                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10635                 # should be able to set brw_size=12, but no rpc_stats for that
10636                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10637         fi
10638
10639         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10640
10641         if [[ $orig_mb -lt 16 ]]; then
10642                 restore_lustre_params < $p
10643                 remount_client $MOUNT || error "remount_client restore failed"
10644         fi
10645
10646         rm -f $p $DIR/$tfile
10647 }
10648 run_test 101g "Big bulk(4/16 MiB) readahead"
10649
10650 test_101h() {
10651         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10652
10653         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10654                 error "dd 70M file failed"
10655         echo Cancel LRU locks on lustre client to flush the client cache
10656         cancel_lru_locks osc
10657
10658         echo "Reset readahead stats"
10659         $LCTL set_param -n llite.*.read_ahead_stats 0
10660
10661         echo "Read 10M of data but cross 64M bundary"
10662         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10663         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10664                      get_named_value 'misses' | calc_total)
10665         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10666         rm -f $p $DIR/$tfile
10667 }
10668 run_test 101h "Readahead should cover current read window"
10669
10670 test_101i() {
10671         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10672                 error "dd 10M file failed"
10673
10674         local max_per_file_mb=$($LCTL get_param -n \
10675                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10676         cancel_lru_locks osc
10677         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10678         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10679                 error "set max_read_ahead_per_file_mb to 1 failed"
10680
10681         echo "Reset readahead stats"
10682         $LCTL set_param llite.*.read_ahead_stats=0
10683
10684         dd if=$DIR/$tfile of=/dev/null bs=2M
10685
10686         $LCTL get_param llite.*.read_ahead_stats
10687         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10688                      awk '/misses/ { print $2 }')
10689         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10690         rm -f $DIR/$tfile
10691 }
10692 run_test 101i "allow current readahead to exceed reservation"
10693
10694 test_101j() {
10695         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10696                 error "setstripe $DIR/$tfile failed"
10697         local file_size=$((1048576 * 16))
10698         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10699         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10700
10701         echo Disable read-ahead
10702         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10703
10704         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10705         for blk in $PAGE_SIZE 1048576 $file_size; do
10706                 cancel_lru_locks osc
10707                 echo "Reset readahead stats"
10708                 $LCTL set_param -n llite.*.read_ahead_stats=0
10709                 local count=$(($file_size / $blk))
10710                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10711                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10712                              get_named_value 'failed.to.fast.read' | calc_total)
10713                 $LCTL get_param -n llite.*.read_ahead_stats
10714                 [ $miss -eq $count ] || error "expected $count got $miss"
10715         done
10716
10717         rm -f $p $DIR/$tfile
10718 }
10719 run_test 101j "A complete read block should be submitted when no RA"
10720
10721 setup_test102() {
10722         test_mkdir $DIR/$tdir
10723         chown $RUNAS_ID $DIR/$tdir
10724         STRIPE_SIZE=65536
10725         STRIPE_OFFSET=1
10726         STRIPE_COUNT=$OSTCOUNT
10727         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10728
10729         trap cleanup_test102 EXIT
10730         cd $DIR
10731         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10732         cd $DIR/$tdir
10733         for num in 1 2 3 4; do
10734                 for count in $(seq 1 $STRIPE_COUNT); do
10735                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10736                                 local size=`expr $STRIPE_SIZE \* $num`
10737                                 local file=file"$num-$idx-$count"
10738                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10739                         done
10740                 done
10741         done
10742
10743         cd $DIR
10744         $1 tar cf $TMP/f102.tar $tdir --xattrs
10745 }
10746
10747 cleanup_test102() {
10748         trap 0
10749         rm -f $TMP/f102.tar
10750         rm -rf $DIR/d0.sanity/d102
10751 }
10752
10753 test_102a() {
10754         [ "$UID" != 0 ] && skip "must run as root"
10755         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10756                 skip_env "must have user_xattr"
10757
10758         [ -z "$(which setfattr 2>/dev/null)" ] &&
10759                 skip_env "could not find setfattr"
10760
10761         local testfile=$DIR/$tfile
10762
10763         touch $testfile
10764         echo "set/get xattr..."
10765         setfattr -n trusted.name1 -v value1 $testfile ||
10766                 error "setfattr -n trusted.name1=value1 $testfile failed"
10767         getfattr -n trusted.name1 $testfile 2> /dev/null |
10768           grep "trusted.name1=.value1" ||
10769                 error "$testfile missing trusted.name1=value1"
10770
10771         setfattr -n user.author1 -v author1 $testfile ||
10772                 error "setfattr -n user.author1=author1 $testfile failed"
10773         getfattr -n user.author1 $testfile 2> /dev/null |
10774           grep "user.author1=.author1" ||
10775                 error "$testfile missing trusted.author1=author1"
10776
10777         echo "listxattr..."
10778         setfattr -n trusted.name2 -v value2 $testfile ||
10779                 error "$testfile unable to set trusted.name2"
10780         setfattr -n trusted.name3 -v value3 $testfile ||
10781                 error "$testfile unable to set trusted.name3"
10782         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10783             grep "trusted.name" | wc -l) -eq 3 ] ||
10784                 error "$testfile missing 3 trusted.name xattrs"
10785
10786         setfattr -n user.author2 -v author2 $testfile ||
10787                 error "$testfile unable to set user.author2"
10788         setfattr -n user.author3 -v author3 $testfile ||
10789                 error "$testfile unable to set user.author3"
10790         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10791             grep "user.author" | wc -l) -eq 3 ] ||
10792                 error "$testfile missing 3 user.author xattrs"
10793
10794         echo "remove xattr..."
10795         setfattr -x trusted.name1 $testfile ||
10796                 error "$testfile error deleting trusted.name1"
10797         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10798                 error "$testfile did not delete trusted.name1 xattr"
10799
10800         setfattr -x user.author1 $testfile ||
10801                 error "$testfile error deleting user.author1"
10802         echo "set lustre special xattr ..."
10803         $LFS setstripe -c1 $testfile
10804         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10805                 awk -F "=" '/trusted.lov/ { print $2 }' )
10806         setfattr -n "trusted.lov" -v $lovea $testfile ||
10807                 error "$testfile doesn't ignore setting trusted.lov again"
10808         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10809                 error "$testfile allow setting invalid trusted.lov"
10810         rm -f $testfile
10811 }
10812 run_test 102a "user xattr test =================================="
10813
10814 check_102b_layout() {
10815         local layout="$*"
10816         local testfile=$DIR/$tfile
10817
10818         echo "test layout '$layout'"
10819         $LFS setstripe $layout $testfile || error "setstripe failed"
10820         $LFS getstripe -y $testfile
10821
10822         echo "get/set/list trusted.lov xattr ..." # b=10930
10823         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10824         [[ "$value" =~ "trusted.lov" ]] ||
10825                 error "can't get trusted.lov from $testfile"
10826         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10827                 error "getstripe failed"
10828
10829         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10830
10831         value=$(cut -d= -f2 <<<$value)
10832         # LU-13168: truncated xattr should fail if short lov_user_md header
10833         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10834                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10835         for len in $lens; do
10836                 echo "setfattr $len $testfile.2"
10837                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10838                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10839         done
10840         local stripe_size=$($LFS getstripe -S $testfile.2)
10841         local stripe_count=$($LFS getstripe -c $testfile.2)
10842         [[ $stripe_size -eq 65536 ]] ||
10843                 error "stripe size $stripe_size != 65536"
10844         [[ $stripe_count -eq $stripe_count_orig ]] ||
10845                 error "stripe count $stripe_count != $stripe_count_orig"
10846         rm $testfile $testfile.2
10847 }
10848
10849 test_102b() {
10850         [ -z "$(which setfattr 2>/dev/null)" ] &&
10851                 skip_env "could not find setfattr"
10852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10853
10854         # check plain layout
10855         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10856
10857         # and also check composite layout
10858         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10859
10860 }
10861 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10862
10863 test_102c() {
10864         [ -z "$(which setfattr 2>/dev/null)" ] &&
10865                 skip_env "could not find setfattr"
10866         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10867
10868         # b10930: get/set/list lustre.lov xattr
10869         echo "get/set/list lustre.lov xattr ..."
10870         test_mkdir $DIR/$tdir
10871         chown $RUNAS_ID $DIR/$tdir
10872         local testfile=$DIR/$tdir/$tfile
10873         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10874                 error "setstripe failed"
10875         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10876                 error "getstripe failed"
10877         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10878         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10879
10880         local testfile2=${testfile}2
10881         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10882                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10883
10884         $RUNAS $MCREATE $testfile2
10885         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10886         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10887         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10888         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10889         [ $stripe_count -eq $STRIPECOUNT ] ||
10890                 error "stripe count $stripe_count != $STRIPECOUNT"
10891 }
10892 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10893
10894 compare_stripe_info1() {
10895         local stripe_index_all_zero=true
10896
10897         for num in 1 2 3 4; do
10898                 for count in $(seq 1 $STRIPE_COUNT); do
10899                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10900                                 local size=$((STRIPE_SIZE * num))
10901                                 local file=file"$num-$offset-$count"
10902                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10903                                 [[ $stripe_size -ne $size ]] &&
10904                                     error "$file: size $stripe_size != $size"
10905                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10906                                 # allow fewer stripes to be created, ORI-601
10907                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10908                                     error "$file: count $stripe_count != $count"
10909                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10910                                 [[ $stripe_index -ne 0 ]] &&
10911                                         stripe_index_all_zero=false
10912                         done
10913                 done
10914         done
10915         $stripe_index_all_zero &&
10916                 error "all files are being extracted starting from OST index 0"
10917         return 0
10918 }
10919
10920 have_xattrs_include() {
10921         tar --help | grep -q xattrs-include &&
10922                 echo --xattrs-include="lustre.*"
10923 }
10924
10925 test_102d() {
10926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10928
10929         XINC=$(have_xattrs_include)
10930         setup_test102
10931         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10932         cd $DIR/$tdir/$tdir
10933         compare_stripe_info1
10934 }
10935 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10936
10937 test_102f() {
10938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10939         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10940
10941         XINC=$(have_xattrs_include)
10942         setup_test102
10943         test_mkdir $DIR/$tdir.restore
10944         cd $DIR
10945         tar cf - --xattrs $tdir | tar xf - \
10946                 -C $DIR/$tdir.restore --xattrs $XINC
10947         cd $DIR/$tdir.restore/$tdir
10948         compare_stripe_info1
10949 }
10950 run_test 102f "tar copy files, not keep osts"
10951
10952 grow_xattr() {
10953         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10954                 skip "must have user_xattr"
10955         [ -z "$(which setfattr 2>/dev/null)" ] &&
10956                 skip_env "could not find setfattr"
10957         [ -z "$(which getfattr 2>/dev/null)" ] &&
10958                 skip_env "could not find getfattr"
10959
10960         local xsize=${1:-1024}  # in bytes
10961         local file=$DIR/$tfile
10962         local value="$(generate_string $xsize)"
10963         local xbig=trusted.big
10964         local toobig=$2
10965
10966         touch $file
10967         log "save $xbig on $file"
10968         if [ -z "$toobig" ]
10969         then
10970                 setfattr -n $xbig -v $value $file ||
10971                         error "saving $xbig on $file failed"
10972         else
10973                 setfattr -n $xbig -v $value $file &&
10974                         error "saving $xbig on $file succeeded"
10975                 return 0
10976         fi
10977
10978         local orig=$(get_xattr_value $xbig $file)
10979         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10980
10981         local xsml=trusted.sml
10982         log "save $xsml on $file"
10983         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10984
10985         local new=$(get_xattr_value $xbig $file)
10986         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10987
10988         log "grow $xsml on $file"
10989         setfattr -n $xsml -v "$value" $file ||
10990                 error "growing $xsml on $file failed"
10991
10992         new=$(get_xattr_value $xbig $file)
10993         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10994         log "$xbig still valid after growing $xsml"
10995
10996         rm -f $file
10997 }
10998
10999 test_102h() { # bug 15777
11000         grow_xattr 1024
11001 }
11002 run_test 102h "grow xattr from inside inode to external block"
11003
11004 test_102ha() {
11005         large_xattr_enabled || skip_env "ea_inode feature disabled"
11006
11007         echo "setting xattr of max xattr size: $(max_xattr_size)"
11008         grow_xattr $(max_xattr_size)
11009
11010         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11011         echo "This should fail:"
11012         grow_xattr $(($(max_xattr_size) + 10)) 1
11013 }
11014 run_test 102ha "grow xattr from inside inode to external inode"
11015
11016 test_102i() { # bug 17038
11017         [ -z "$(which getfattr 2>/dev/null)" ] &&
11018                 skip "could not find getfattr"
11019
11020         touch $DIR/$tfile
11021         ln -s $DIR/$tfile $DIR/${tfile}link
11022         getfattr -n trusted.lov $DIR/$tfile ||
11023                 error "lgetxattr on $DIR/$tfile failed"
11024         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11025                 grep -i "no such attr" ||
11026                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11027         rm -f $DIR/$tfile $DIR/${tfile}link
11028 }
11029 run_test 102i "lgetxattr test on symbolic link ============"
11030
11031 test_102j() {
11032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11033         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11034
11035         XINC=$(have_xattrs_include)
11036         setup_test102 "$RUNAS"
11037         chown $RUNAS_ID $DIR/$tdir
11038         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11039         cd $DIR/$tdir/$tdir
11040         compare_stripe_info1 "$RUNAS"
11041 }
11042 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11043
11044 test_102k() {
11045         [ -z "$(which setfattr 2>/dev/null)" ] &&
11046                 skip "could not find setfattr"
11047
11048         touch $DIR/$tfile
11049         # b22187 just check that does not crash for regular file.
11050         setfattr -n trusted.lov $DIR/$tfile
11051         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11052         local test_kdir=$DIR/$tdir
11053         test_mkdir $test_kdir
11054         local default_size=$($LFS getstripe -S $test_kdir)
11055         local default_count=$($LFS getstripe -c $test_kdir)
11056         local default_offset=$($LFS getstripe -i $test_kdir)
11057         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11058                 error 'dir setstripe failed'
11059         setfattr -n trusted.lov $test_kdir
11060         local stripe_size=$($LFS getstripe -S $test_kdir)
11061         local stripe_count=$($LFS getstripe -c $test_kdir)
11062         local stripe_offset=$($LFS getstripe -i $test_kdir)
11063         [ $stripe_size -eq $default_size ] ||
11064                 error "stripe size $stripe_size != $default_size"
11065         [ $stripe_count -eq $default_count ] ||
11066                 error "stripe count $stripe_count != $default_count"
11067         [ $stripe_offset -eq $default_offset ] ||
11068                 error "stripe offset $stripe_offset != $default_offset"
11069         rm -rf $DIR/$tfile $test_kdir
11070 }
11071 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11072
11073 test_102l() {
11074         [ -z "$(which getfattr 2>/dev/null)" ] &&
11075                 skip "could not find getfattr"
11076
11077         # LU-532 trusted. xattr is invisible to non-root
11078         local testfile=$DIR/$tfile
11079
11080         touch $testfile
11081
11082         echo "listxattr as user..."
11083         chown $RUNAS_ID $testfile
11084         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11085             grep -q "trusted" &&
11086                 error "$testfile trusted xattrs are user visible"
11087
11088         return 0;
11089 }
11090 run_test 102l "listxattr size test =================================="
11091
11092 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11093         local path=$DIR/$tfile
11094         touch $path
11095
11096         listxattr_size_check $path || error "listattr_size_check $path failed"
11097 }
11098 run_test 102m "Ensure listxattr fails on small bufffer ========"
11099
11100 cleanup_test102
11101
11102 getxattr() { # getxattr path name
11103         # Return the base64 encoding of the value of xattr name on path.
11104         local path=$1
11105         local name=$2
11106
11107         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11108         # file: $path
11109         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11110         #
11111         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11112
11113         getfattr --absolute-names --encoding=base64 --name=$name $path |
11114                 awk -F= -v name=$name '$1 == name {
11115                         print substr($0, index($0, "=") + 1);
11116         }'
11117 }
11118
11119 test_102n() { # LU-4101 mdt: protect internal xattrs
11120         [ -z "$(which setfattr 2>/dev/null)" ] &&
11121                 skip "could not find setfattr"
11122         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11123         then
11124                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11125         fi
11126
11127         local file0=$DIR/$tfile.0
11128         local file1=$DIR/$tfile.1
11129         local xattr0=$TMP/$tfile.0
11130         local xattr1=$TMP/$tfile.1
11131         local namelist="lov lma lmv link fid version som hsm"
11132         local name
11133         local value
11134
11135         rm -rf $file0 $file1 $xattr0 $xattr1
11136         touch $file0 $file1
11137
11138         # Get 'before' xattrs of $file1.
11139         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11140
11141         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11142                 namelist+=" lfsck_namespace"
11143         for name in $namelist; do
11144                 # Try to copy xattr from $file0 to $file1.
11145                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11146
11147                 setfattr --name=trusted.$name --value="$value" $file1 ||
11148                         error "setxattr 'trusted.$name' failed"
11149
11150                 # Try to set a garbage xattr.
11151                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11152
11153                 if [[ x$name == "xlov" ]]; then
11154                         setfattr --name=trusted.lov --value="$value" $file1 &&
11155                         error "setxattr invalid 'trusted.lov' success"
11156                 else
11157                         setfattr --name=trusted.$name --value="$value" $file1 ||
11158                                 error "setxattr invalid 'trusted.$name' failed"
11159                 fi
11160
11161                 # Try to remove the xattr from $file1. We don't care if this
11162                 # appears to succeed or fail, we just don't want there to be
11163                 # any changes or crashes.
11164                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11165         done
11166
11167         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11168         then
11169                 name="lfsck_ns"
11170                 # Try to copy xattr from $file0 to $file1.
11171                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11172
11173                 setfattr --name=trusted.$name --value="$value" $file1 ||
11174                         error "setxattr 'trusted.$name' failed"
11175
11176                 # Try to set a garbage xattr.
11177                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11178
11179                 setfattr --name=trusted.$name --value="$value" $file1 ||
11180                         error "setxattr 'trusted.$name' failed"
11181
11182                 # Try to remove the xattr from $file1. We don't care if this
11183                 # appears to succeed or fail, we just don't want there to be
11184                 # any changes or crashes.
11185                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11186         fi
11187
11188         # Get 'after' xattrs of file1.
11189         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11190
11191         if ! diff $xattr0 $xattr1; then
11192                 error "before and after xattrs of '$file1' differ"
11193         fi
11194
11195         rm -rf $file0 $file1 $xattr0 $xattr1
11196
11197         return 0
11198 }
11199 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11200
11201 test_102p() { # LU-4703 setxattr did not check ownership
11202         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11203                 skip "MDS needs to be at least 2.5.56"
11204
11205         local testfile=$DIR/$tfile
11206
11207         touch $testfile
11208
11209         echo "setfacl as user..."
11210         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11211         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11212
11213         echo "setfattr as user..."
11214         setfacl -m "u:$RUNAS_ID:---" $testfile
11215         $RUNAS setfattr -x system.posix_acl_access $testfile
11216         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11217 }
11218 run_test 102p "check setxattr(2) correctly fails without permission"
11219
11220 test_102q() {
11221         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11222                 skip "MDS needs to be at least 2.6.92"
11223
11224         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11225 }
11226 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11227
11228 test_102r() {
11229         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11230                 skip "MDS needs to be at least 2.6.93"
11231
11232         touch $DIR/$tfile || error "touch"
11233         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11234         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11235         rm $DIR/$tfile || error "rm"
11236
11237         #normal directory
11238         mkdir -p $DIR/$tdir || error "mkdir"
11239         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11240         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11241         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11242                 error "$testfile error deleting user.author1"
11243         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11244                 grep "user.$(basename $tdir)" &&
11245                 error "$tdir did not delete user.$(basename $tdir)"
11246         rmdir $DIR/$tdir || error "rmdir"
11247
11248         #striped directory
11249         test_mkdir $DIR/$tdir
11250         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11251         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11252         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11253                 error "$testfile error deleting user.author1"
11254         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11255                 grep "user.$(basename $tdir)" &&
11256                 error "$tdir did not delete user.$(basename $tdir)"
11257         rmdir $DIR/$tdir || error "rm striped dir"
11258 }
11259 run_test 102r "set EAs with empty values"
11260
11261 test_102s() {
11262         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11263                 skip "MDS needs to be at least 2.11.52"
11264
11265         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11266
11267         save_lustre_params client "llite.*.xattr_cache" > $save
11268
11269         for cache in 0 1; do
11270                 lctl set_param llite.*.xattr_cache=$cache
11271
11272                 rm -f $DIR/$tfile
11273                 touch $DIR/$tfile || error "touch"
11274                 for prefix in lustre security system trusted user; do
11275                         # Note getxattr() may fail with 'Operation not
11276                         # supported' or 'No such attribute' depending
11277                         # on prefix and cache.
11278                         getfattr -n $prefix.n102s $DIR/$tfile &&
11279                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11280                 done
11281         done
11282
11283         restore_lustre_params < $save
11284 }
11285 run_test 102s "getting nonexistent xattrs should fail"
11286
11287 test_102t() {
11288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11289                 skip "MDS needs to be at least 2.11.52"
11290
11291         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11292
11293         save_lustre_params client "llite.*.xattr_cache" > $save
11294
11295         for cache in 0 1; do
11296                 lctl set_param llite.*.xattr_cache=$cache
11297
11298                 for buf_size in 0 256; do
11299                         rm -f $DIR/$tfile
11300                         touch $DIR/$tfile || error "touch"
11301                         setfattr -n user.multiop $DIR/$tfile
11302                         $MULTIOP $DIR/$tfile oa$buf_size ||
11303                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11304                 done
11305         done
11306
11307         restore_lustre_params < $save
11308 }
11309 run_test 102t "zero length xattr values handled correctly"
11310
11311 run_acl_subtest()
11312 {
11313     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11314     return $?
11315 }
11316
11317 test_103a() {
11318         [ "$UID" != 0 ] && skip "must run as root"
11319         $GSS && skip_env "could not run under gss"
11320         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11321                 skip_env "must have acl enabled"
11322         [ -z "$(which setfacl 2>/dev/null)" ] &&
11323                 skip_env "could not find setfacl"
11324         remote_mds_nodsh && skip "remote MDS with nodsh"
11325
11326         gpasswd -a daemon bin                           # LU-5641
11327         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11328
11329         declare -a identity_old
11330
11331         for num in $(seq $MDSCOUNT); do
11332                 switch_identity $num true || identity_old[$num]=$?
11333         done
11334
11335         SAVE_UMASK=$(umask)
11336         umask 0022
11337         mkdir -p $DIR/$tdir
11338         cd $DIR/$tdir
11339
11340         echo "performing cp ..."
11341         run_acl_subtest cp || error "run_acl_subtest cp failed"
11342         echo "performing getfacl-noacl..."
11343         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11344         echo "performing misc..."
11345         run_acl_subtest misc || error  "misc test failed"
11346         echo "performing permissions..."
11347         run_acl_subtest permissions || error "permissions failed"
11348         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11349         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11350                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11351                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11352         then
11353                 echo "performing permissions xattr..."
11354                 run_acl_subtest permissions_xattr ||
11355                         error "permissions_xattr failed"
11356         fi
11357         echo "performing setfacl..."
11358         run_acl_subtest setfacl || error  "setfacl test failed"
11359
11360         # inheritance test got from HP
11361         echo "performing inheritance..."
11362         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11363         chmod +x make-tree || error "chmod +x failed"
11364         run_acl_subtest inheritance || error "inheritance test failed"
11365         rm -f make-tree
11366
11367         echo "LU-974 ignore umask when acl is enabled..."
11368         run_acl_subtest 974 || error "LU-974 umask test failed"
11369         if [ $MDSCOUNT -ge 2 ]; then
11370                 run_acl_subtest 974_remote ||
11371                         error "LU-974 umask test failed under remote dir"
11372         fi
11373
11374         echo "LU-2561 newly created file is same size as directory..."
11375         if [ "$mds1_FSTYPE" != "zfs" ]; then
11376                 run_acl_subtest 2561 || error "LU-2561 test failed"
11377         else
11378                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11379         fi
11380
11381         run_acl_subtest 4924 || error "LU-4924 test failed"
11382
11383         cd $SAVE_PWD
11384         umask $SAVE_UMASK
11385
11386         for num in $(seq $MDSCOUNT); do
11387                 if [ "${identity_old[$num]}" = 1 ]; then
11388                         switch_identity $num false || identity_old[$num]=$?
11389                 fi
11390         done
11391 }
11392 run_test 103a "acl test"
11393
11394 test_103b() {
11395         declare -a pids
11396         local U
11397
11398         for U in {0..511}; do
11399                 {
11400                 local O=$(printf "%04o" $U)
11401
11402                 umask $(printf "%04o" $((511 ^ $O)))
11403                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11404                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11405
11406                 (( $S == ($O & 0666) )) ||
11407                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11408
11409                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11410                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11411                 (( $S == ($O & 0666) )) ||
11412                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11413
11414                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11415                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11416                 (( $S == ($O & 0666) )) ||
11417                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11418                 rm -f $DIR/$tfile.[smp]$0
11419                 } &
11420                 local pid=$!
11421
11422                 # limit the concurrently running threads to 64. LU-11878
11423                 local idx=$((U % 64))
11424                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11425                 pids[idx]=$pid
11426         done
11427         wait
11428 }
11429 run_test 103b "umask lfs setstripe"
11430
11431 test_103c() {
11432         mkdir -p $DIR/$tdir
11433         cp -rp $DIR/$tdir $DIR/$tdir.bak
11434
11435         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11436                 error "$DIR/$tdir shouldn't contain default ACL"
11437         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11438                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11439         true
11440 }
11441 run_test 103c "'cp -rp' won't set empty acl"
11442
11443 test_103e() {
11444         local numacl
11445         local fileacl
11446         local saved_debug=$($LCTL get_param -n debug)
11447
11448         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11449                 skip "MDS needs to be at least 2.14.0"
11450
11451         large_xattr_enabled || skip_env "ea_inode feature disabled"
11452
11453         mkdir -p $DIR/$tdir
11454         # add big LOV EA to cause reply buffer overflow earlier
11455         $LFS setstripe -C 1000 $DIR/$tdir
11456         lctl set_param mdc.*-mdc*.stats=clear
11457
11458         $LCTL set_param debug=0
11459         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11460         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11461
11462         # add a large number of default ACLs (expect 8000+ for 2.13+)
11463         for U in {2..7000}; do
11464                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11465                         error "Able to add just $U default ACLs"
11466         done
11467         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11468         echo "$numacl default ACLs created"
11469
11470         stat $DIR/$tdir || error "Cannot stat directory"
11471         # check file creation
11472         touch $DIR/$tdir/$tfile ||
11473                 error "failed to create $tfile with $numacl default ACLs"
11474         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11475         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11476         echo "$fileacl ACLs were inherited"
11477         (( $fileacl == $numacl )) ||
11478                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11479         # check that new ACLs creation adds new ACLs to inherited ACLs
11480         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11481                 error "Cannot set new ACL"
11482         numacl=$((numacl + 1))
11483         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11484         (( $fileacl == $numacl )) ||
11485                 error "failed to add new ACL: $fileacl != $numacl as expected"
11486         # adds more ACLs to a file to reach their maximum at 8000+
11487         numacl=0
11488         for U in {20000..25000}; do
11489                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11490                 numacl=$((numacl + 1))
11491         done
11492         echo "Added $numacl more ACLs to the file"
11493         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11494         echo "Total $fileacl ACLs in file"
11495         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11496         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11497         rmdir $DIR/$tdir || error "Cannot remove directory"
11498 }
11499 run_test 103e "inheritance of big amount of default ACLs"
11500
11501 test_103f() {
11502         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11503                 skip "MDS needs to be at least 2.14.51"
11504
11505         large_xattr_enabled || skip_env "ea_inode feature disabled"
11506
11507         # enable changelog to consume more internal MDD buffers
11508         changelog_register
11509
11510         mkdir -p $DIR/$tdir
11511         # add big LOV EA
11512         $LFS setstripe -C 1000 $DIR/$tdir
11513         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11514         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11515         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11516         rmdir $DIR/$tdir || error "Cannot remove directory"
11517 }
11518 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11519
11520 test_104a() {
11521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11522
11523         touch $DIR/$tfile
11524         lfs df || error "lfs df failed"
11525         lfs df -ih || error "lfs df -ih failed"
11526         lfs df -h $DIR || error "lfs df -h $DIR failed"
11527         lfs df -i $DIR || error "lfs df -i $DIR failed"
11528         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11529         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11530
11531         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11532         lctl --device %$OSC deactivate
11533         lfs df || error "lfs df with deactivated OSC failed"
11534         lctl --device %$OSC activate
11535         # wait the osc back to normal
11536         wait_osc_import_ready client ost
11537
11538         lfs df || error "lfs df with reactivated OSC failed"
11539         rm -f $DIR/$tfile
11540 }
11541 run_test 104a "lfs df [-ih] [path] test ========================="
11542
11543 test_104b() {
11544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11545         [ $RUNAS_ID -eq $UID ] &&
11546                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11547
11548         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11549                         grep "Permission denied" | wc -l)))
11550         if [ $denied_cnt -ne 0 ]; then
11551                 error "lfs check servers test failed"
11552         fi
11553 }
11554 run_test 104b "$RUNAS lfs check servers test ===================="
11555
11556 #
11557 # Verify $1 is within range of $2.
11558 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11559 # $1 is <= 2% of $2. Else Fail.
11560 #
11561 value_in_range() {
11562         # Strip all units (M, G, T)
11563         actual=$(echo $1 | tr -d A-Z)
11564         expect=$(echo $2 | tr -d A-Z)
11565
11566         expect_lo=$(($expect * 98 / 100)) # 2% below
11567         expect_hi=$(($expect * 102 / 100)) # 2% above
11568
11569         # permit 2% drift above and below
11570         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11571 }
11572
11573 test_104c() {
11574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11575         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11576
11577         local ost_param="osd-zfs.$FSNAME-OST0000."
11578         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11579         local ofacets=$(get_facets OST)
11580         local mfacets=$(get_facets MDS)
11581         local saved_ost_blocks=
11582         local saved_mdt_blocks=
11583
11584         echo "Before recordsize change"
11585         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11586         df=($(df -h | grep "/mnt/lustre"$))
11587
11588         # For checking.
11589         echo "lfs output : ${lfs_df[*]}"
11590         echo "df  output : ${df[*]}"
11591
11592         for facet in ${ofacets//,/ }; do
11593                 if [ -z $saved_ost_blocks ]; then
11594                         saved_ost_blocks=$(do_facet $facet \
11595                                 lctl get_param -n $ost_param.blocksize)
11596                         echo "OST Blocksize: $saved_ost_blocks"
11597                 fi
11598                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11599                 do_facet $facet zfs set recordsize=32768 $ost
11600         done
11601
11602         # BS too small. Sufficient for functional testing.
11603         for facet in ${mfacets//,/ }; do
11604                 if [ -z $saved_mdt_blocks ]; then
11605                         saved_mdt_blocks=$(do_facet $facet \
11606                                 lctl get_param -n $mdt_param.blocksize)
11607                         echo "MDT Blocksize: $saved_mdt_blocks"
11608                 fi
11609                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11610                 do_facet $facet zfs set recordsize=32768 $mdt
11611         done
11612
11613         # Give new values chance to reflect change
11614         sleep 2
11615
11616         echo "After recordsize change"
11617         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11618         df_after=($(df -h | grep "/mnt/lustre"$))
11619
11620         # For checking.
11621         echo "lfs output : ${lfs_df_after[*]}"
11622         echo "df  output : ${df_after[*]}"
11623
11624         # Verify lfs df
11625         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11626                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11627         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11628                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11629         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11630                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11631
11632         # Verify df
11633         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11634                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11635         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11636                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11637         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11638                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11639
11640         # Restore MDT recordize back to original
11641         for facet in ${mfacets//,/ }; do
11642                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11643                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11644         done
11645
11646         # Restore OST recordize back to original
11647         for facet in ${ofacets//,/ }; do
11648                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11649                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11650         done
11651
11652         return 0
11653 }
11654 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11655
11656 test_105a() {
11657         # doesn't work on 2.4 kernels
11658         touch $DIR/$tfile
11659         if $(flock_is_enabled); then
11660                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11661         else
11662                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11663         fi
11664         rm -f $DIR/$tfile
11665 }
11666 run_test 105a "flock when mounted without -o flock test ========"
11667
11668 test_105b() {
11669         touch $DIR/$tfile
11670         if $(flock_is_enabled); then
11671                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11672         else
11673                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11674         fi
11675         rm -f $DIR/$tfile
11676 }
11677 run_test 105b "fcntl when mounted without -o flock test ========"
11678
11679 test_105c() {
11680         touch $DIR/$tfile
11681         if $(flock_is_enabled); then
11682                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11683         else
11684                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11685         fi
11686         rm -f $DIR/$tfile
11687 }
11688 run_test 105c "lockf when mounted without -o flock test"
11689
11690 test_105d() { # bug 15924
11691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11692
11693         test_mkdir $DIR/$tdir
11694         flock_is_enabled || skip_env "mount w/o flock enabled"
11695         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11696         $LCTL set_param fail_loc=0x80000315
11697         flocks_test 2 $DIR/$tdir
11698 }
11699 run_test 105d "flock race (should not freeze) ========"
11700
11701 test_105e() { # bug 22660 && 22040
11702         flock_is_enabled || skip_env "mount w/o flock enabled"
11703
11704         touch $DIR/$tfile
11705         flocks_test 3 $DIR/$tfile
11706 }
11707 run_test 105e "Two conflicting flocks from same process"
11708
11709 test_106() { #bug 10921
11710         test_mkdir $DIR/$tdir
11711         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11712         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11713 }
11714 run_test 106 "attempt exec of dir followed by chown of that dir"
11715
11716 test_107() {
11717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11718
11719         CDIR=`pwd`
11720         local file=core
11721
11722         cd $DIR
11723         rm -f $file
11724
11725         local save_pattern=$(sysctl -n kernel.core_pattern)
11726         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11727         sysctl -w kernel.core_pattern=$file
11728         sysctl -w kernel.core_uses_pid=0
11729
11730         ulimit -c unlimited
11731         sleep 60 &
11732         SLEEPPID=$!
11733
11734         sleep 1
11735
11736         kill -s 11 $SLEEPPID
11737         wait $SLEEPPID
11738         if [ -e $file ]; then
11739                 size=`stat -c%s $file`
11740                 [ $size -eq 0 ] && error "Fail to create core file $file"
11741         else
11742                 error "Fail to create core file $file"
11743         fi
11744         rm -f $file
11745         sysctl -w kernel.core_pattern=$save_pattern
11746         sysctl -w kernel.core_uses_pid=$save_uses_pid
11747         cd $CDIR
11748 }
11749 run_test 107 "Coredump on SIG"
11750
11751 test_110() {
11752         test_mkdir $DIR/$tdir
11753         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11754         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11755                 error "mkdir with 256 char should fail, but did not"
11756         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11757                 error "create with 255 char failed"
11758         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11759                 error "create with 256 char should fail, but did not"
11760
11761         ls -l $DIR/$tdir
11762         rm -rf $DIR/$tdir
11763 }
11764 run_test 110 "filename length checking"
11765
11766 #
11767 # Purpose: To verify dynamic thread (OSS) creation.
11768 #
11769 test_115() {
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771         remote_ost_nodsh && skip "remote OST with nodsh"
11772
11773         # Lustre does not stop service threads once they are started.
11774         # Reset number of running threads to default.
11775         stopall
11776         setupall
11777
11778         local OSTIO_pre
11779         local save_params="$TMP/sanity-$TESTNAME.parameters"
11780
11781         # Get ll_ost_io count before I/O
11782         OSTIO_pre=$(do_facet ost1 \
11783                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11784         # Exit if lustre is not running (ll_ost_io not running).
11785         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11786
11787         echo "Starting with $OSTIO_pre threads"
11788         local thread_max=$((OSTIO_pre * 2))
11789         local rpc_in_flight=$((thread_max * 2))
11790         # Number of I/O Process proposed to be started.
11791         local nfiles
11792         local facets=$(get_facets OST)
11793
11794         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11795         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11796
11797         # Set in_flight to $rpc_in_flight
11798         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11799                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11800         nfiles=${rpc_in_flight}
11801         # Set ost thread_max to $thread_max
11802         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11803
11804         # 5 Minutes should be sufficient for max number of OSS
11805         # threads(thread_max) to be created.
11806         local timeout=300
11807
11808         # Start I/O.
11809         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11810         test_mkdir $DIR/$tdir
11811         for i in $(seq $nfiles); do
11812                 local file=$DIR/$tdir/${tfile}-$i
11813                 $LFS setstripe -c -1 -i 0 $file
11814                 ($WTL $file $timeout)&
11815         done
11816
11817         # I/O Started - Wait for thread_started to reach thread_max or report
11818         # error if thread_started is more than thread_max.
11819         echo "Waiting for thread_started to reach thread_max"
11820         local thread_started=0
11821         local end_time=$((SECONDS + timeout))
11822
11823         while [ $SECONDS -le $end_time ] ; do
11824                 echo -n "."
11825                 # Get ost i/o thread_started count.
11826                 thread_started=$(do_facet ost1 \
11827                         "$LCTL get_param \
11828                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11829                 # Break out if thread_started is equal/greater than thread_max
11830                 if [[ $thread_started -ge $thread_max ]]; then
11831                         echo ll_ost_io thread_started $thread_started, \
11832                                 equal/greater than thread_max $thread_max
11833                         break
11834                 fi
11835                 sleep 1
11836         done
11837
11838         # Cleanup - We have the numbers, Kill i/o jobs if running.
11839         jobcount=($(jobs -p))
11840         for i in $(seq 0 $((${#jobcount[@]}-1)))
11841         do
11842                 kill -9 ${jobcount[$i]}
11843                 if [ $? -ne 0 ] ; then
11844                         echo Warning: \
11845                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11846                 fi
11847         done
11848
11849         # Cleanup files left by WTL binary.
11850         for i in $(seq $nfiles); do
11851                 local file=$DIR/$tdir/${tfile}-$i
11852                 rm -rf $file
11853                 if [ $? -ne 0 ] ; then
11854                         echo "Warning: Failed to delete file $file"
11855                 fi
11856         done
11857
11858         restore_lustre_params <$save_params
11859         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11860
11861         # Error out if no new thread has started or Thread started is greater
11862         # than thread max.
11863         if [[ $thread_started -le $OSTIO_pre ||
11864                         $thread_started -gt $thread_max ]]; then
11865                 error "ll_ost_io: thread_started $thread_started" \
11866                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11867                       "No new thread started or thread started greater " \
11868                       "than thread_max."
11869         fi
11870 }
11871 run_test 115 "verify dynamic thread creation===================="
11872
11873 free_min_max () {
11874         wait_delete_completed
11875         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11876         echo "OST kbytes available: ${AVAIL[@]}"
11877         MAXV=${AVAIL[0]}
11878         MAXI=0
11879         MINV=${AVAIL[0]}
11880         MINI=0
11881         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11882                 #echo OST $i: ${AVAIL[i]}kb
11883                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11884                         MAXV=${AVAIL[i]}
11885                         MAXI=$i
11886                 fi
11887                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11888                         MINV=${AVAIL[i]}
11889                         MINI=$i
11890                 fi
11891         done
11892         echo "Min free space: OST $MINI: $MINV"
11893         echo "Max free space: OST $MAXI: $MAXV"
11894 }
11895
11896 test_116a() { # was previously test_116()
11897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11898         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11899         remote_mds_nodsh && skip "remote MDS with nodsh"
11900
11901         echo -n "Free space priority "
11902         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11903                 head -n1
11904         declare -a AVAIL
11905         free_min_max
11906
11907         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11908         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11909         stack_trap simple_cleanup_common
11910
11911         # Check if we need to generate uneven OSTs
11912         test_mkdir -p $DIR/$tdir/OST${MINI}
11913         local FILL=$((MINV / 4))
11914         local DIFF=$((MAXV - MINV))
11915         local DIFF2=$((DIFF * 100 / MINV))
11916
11917         local threshold=$(do_facet $SINGLEMDS \
11918                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11919         threshold=${threshold%%%}
11920         echo -n "Check for uneven OSTs: "
11921         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11922
11923         if [[ $DIFF2 -gt $threshold ]]; then
11924                 echo "ok"
11925                 echo "Don't need to fill OST$MINI"
11926         else
11927                 # generate uneven OSTs. Write 2% over the QOS threshold value
11928                 echo "no"
11929                 DIFF=$((threshold - DIFF2 + 2))
11930                 DIFF2=$((MINV * DIFF / 100))
11931                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11932                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11933                         error "setstripe failed"
11934                 DIFF=$((DIFF2 / 2048))
11935                 i=0
11936                 while [ $i -lt $DIFF ]; do
11937                         i=$((i + 1))
11938                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11939                                 bs=2M count=1 2>/dev/null
11940                         echo -n .
11941                 done
11942                 echo .
11943                 sync
11944                 sleep_maxage
11945                 free_min_max
11946         fi
11947
11948         DIFF=$((MAXV - MINV))
11949         DIFF2=$((DIFF * 100 / MINV))
11950         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11951         if [ $DIFF2 -gt $threshold ]; then
11952                 echo "ok"
11953         else
11954                 skip "QOS imbalance criteria not met"
11955         fi
11956
11957         MINI1=$MINI
11958         MINV1=$MINV
11959         MAXI1=$MAXI
11960         MAXV1=$MAXV
11961
11962         # now fill using QOS
11963         $LFS setstripe -c 1 $DIR/$tdir
11964         FILL=$((FILL / 200))
11965         if [ $FILL -gt 600 ]; then
11966                 FILL=600
11967         fi
11968         echo "writing $FILL files to QOS-assigned OSTs"
11969         i=0
11970         while [ $i -lt $FILL ]; do
11971                 i=$((i + 1))
11972                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11973                         count=1 2>/dev/null
11974                 echo -n .
11975         done
11976         echo "wrote $i 200k files"
11977         sync
11978         sleep_maxage
11979
11980         echo "Note: free space may not be updated, so measurements might be off"
11981         free_min_max
11982         DIFF2=$((MAXV - MINV))
11983         echo "free space delta: orig $DIFF final $DIFF2"
11984         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11985         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11986         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11987         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11988         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11989         if [[ $DIFF -gt 0 ]]; then
11990                 FILL=$((DIFF2 * 100 / DIFF - 100))
11991                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11992         fi
11993
11994         # Figure out which files were written where
11995         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11996                awk '/'$MINI1': / {print $2; exit}')
11997         echo $UUID
11998         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11999         echo "$MINC files created on smaller OST $MINI1"
12000         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12001                awk '/'$MAXI1': / {print $2; exit}')
12002         echo $UUID
12003         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12004         echo "$MAXC files created on larger OST $MAXI1"
12005         if [[ $MINC -gt 0 ]]; then
12006                 FILL=$((MAXC * 100 / MINC - 100))
12007                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12008         fi
12009         [[ $MAXC -gt $MINC ]] ||
12010                 error_ignore LU-9 "stripe QOS didn't balance free space"
12011 }
12012 run_test 116a "stripe QOS: free space balance ==================="
12013
12014 test_116b() { # LU-2093
12015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12016         remote_mds_nodsh && skip "remote MDS with nodsh"
12017
12018 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12019         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12020                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12021         [ -z "$old_rr" ] && skip "no QOS"
12022         do_facet $SINGLEMDS lctl set_param \
12023                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12024         mkdir -p $DIR/$tdir
12025         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12026         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12027         do_facet $SINGLEMDS lctl set_param fail_loc=0
12028         rm -rf $DIR/$tdir
12029         do_facet $SINGLEMDS lctl set_param \
12030                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12031 }
12032 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12033
12034 test_117() # bug 10891
12035 {
12036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12037
12038         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12039         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12040         lctl set_param fail_loc=0x21e
12041         > $DIR/$tfile || error "truncate failed"
12042         lctl set_param fail_loc=0
12043         echo "Truncate succeeded."
12044         rm -f $DIR/$tfile
12045 }
12046 run_test 117 "verify osd extend =========="
12047
12048 NO_SLOW_RESENDCOUNT=4
12049 export OLD_RESENDCOUNT=""
12050 set_resend_count () {
12051         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12052         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12053         lctl set_param -n $PROC_RESENDCOUNT $1
12054         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12055 }
12056
12057 # for reduce test_118* time (b=14842)
12058 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12059
12060 # Reset async IO behavior after error case
12061 reset_async() {
12062         FILE=$DIR/reset_async
12063
12064         # Ensure all OSCs are cleared
12065         $LFS setstripe -c -1 $FILE
12066         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12067         sync
12068         rm $FILE
12069 }
12070
12071 test_118a() #bug 11710
12072 {
12073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12074
12075         reset_async
12076
12077         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12078         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12079         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12080
12081         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12082                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12083                 return 1;
12084         fi
12085         rm -f $DIR/$tfile
12086 }
12087 run_test 118a "verify O_SYNC works =========="
12088
12089 test_118b()
12090 {
12091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12092         remote_ost_nodsh && skip "remote OST with nodsh"
12093
12094         reset_async
12095
12096         #define OBD_FAIL_SRV_ENOENT 0x217
12097         set_nodes_failloc "$(osts_nodes)" 0x217
12098         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12099         RC=$?
12100         set_nodes_failloc "$(osts_nodes)" 0
12101         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12102         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12103                     grep -c writeback)
12104
12105         if [[ $RC -eq 0 ]]; then
12106                 error "Must return error due to dropped pages, rc=$RC"
12107                 return 1;
12108         fi
12109
12110         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12111                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12112                 return 1;
12113         fi
12114
12115         echo "Dirty pages not leaked on ENOENT"
12116
12117         # Due to the above error the OSC will issue all RPCs syncronously
12118         # until a subsequent RPC completes successfully without error.
12119         $MULTIOP $DIR/$tfile Ow4096yc
12120         rm -f $DIR/$tfile
12121
12122         return 0
12123 }
12124 run_test 118b "Reclaim dirty pages on fatal error =========="
12125
12126 test_118c()
12127 {
12128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12129
12130         # for 118c, restore the original resend count, LU-1940
12131         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12132                                 set_resend_count $OLD_RESENDCOUNT
12133         remote_ost_nodsh && skip "remote OST with nodsh"
12134
12135         reset_async
12136
12137         #define OBD_FAIL_OST_EROFS               0x216
12138         set_nodes_failloc "$(osts_nodes)" 0x216
12139
12140         # multiop should block due to fsync until pages are written
12141         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12142         MULTIPID=$!
12143         sleep 1
12144
12145         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12146                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12147         fi
12148
12149         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12150                     grep -c writeback)
12151         if [[ $WRITEBACK -eq 0 ]]; then
12152                 error "No page in writeback, writeback=$WRITEBACK"
12153         fi
12154
12155         set_nodes_failloc "$(osts_nodes)" 0
12156         wait $MULTIPID
12157         RC=$?
12158         if [[ $RC -ne 0 ]]; then
12159                 error "Multiop fsync failed, rc=$RC"
12160         fi
12161
12162         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12163         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12164                     grep -c writeback)
12165         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12166                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12167         fi
12168
12169         rm -f $DIR/$tfile
12170         echo "Dirty pages flushed via fsync on EROFS"
12171         return 0
12172 }
12173 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12174
12175 # continue to use small resend count to reduce test_118* time (b=14842)
12176 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12177
12178 test_118d()
12179 {
12180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12181         remote_ost_nodsh && skip "remote OST with nodsh"
12182
12183         reset_async
12184
12185         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12186         set_nodes_failloc "$(osts_nodes)" 0x214
12187         # multiop should block due to fsync until pages are written
12188         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12189         MULTIPID=$!
12190         sleep 1
12191
12192         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12193                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12194         fi
12195
12196         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12197                     grep -c writeback)
12198         if [[ $WRITEBACK -eq 0 ]]; then
12199                 error "No page in writeback, writeback=$WRITEBACK"
12200         fi
12201
12202         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12203         set_nodes_failloc "$(osts_nodes)" 0
12204
12205         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12206         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12207                     grep -c writeback)
12208         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12209                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12210         fi
12211
12212         rm -f $DIR/$tfile
12213         echo "Dirty pages gaurenteed flushed via fsync"
12214         return 0
12215 }
12216 run_test 118d "Fsync validation inject a delay of the bulk =========="
12217
12218 test_118f() {
12219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12220
12221         reset_async
12222
12223         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12224         lctl set_param fail_loc=0x8000040a
12225
12226         # Should simulate EINVAL error which is fatal
12227         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12228         RC=$?
12229         if [[ $RC -eq 0 ]]; then
12230                 error "Must return error due to dropped pages, rc=$RC"
12231         fi
12232
12233         lctl set_param fail_loc=0x0
12234
12235         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12236         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12237         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12238                     grep -c writeback)
12239         if [[ $LOCKED -ne 0 ]]; then
12240                 error "Locked pages remain in cache, locked=$LOCKED"
12241         fi
12242
12243         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12244                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12245         fi
12246
12247         rm -f $DIR/$tfile
12248         echo "No pages locked after fsync"
12249
12250         reset_async
12251         return 0
12252 }
12253 run_test 118f "Simulate unrecoverable OSC side error =========="
12254
12255 test_118g() {
12256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12257
12258         reset_async
12259
12260         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12261         lctl set_param fail_loc=0x406
12262
12263         # simulate local -ENOMEM
12264         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12265         RC=$?
12266
12267         lctl set_param fail_loc=0
12268         if [[ $RC -eq 0 ]]; then
12269                 error "Must return error due to dropped pages, rc=$RC"
12270         fi
12271
12272         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12273         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12274         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12275                         grep -c writeback)
12276         if [[ $LOCKED -ne 0 ]]; then
12277                 error "Locked pages remain in cache, locked=$LOCKED"
12278         fi
12279
12280         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12281                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12282         fi
12283
12284         rm -f $DIR/$tfile
12285         echo "No pages locked after fsync"
12286
12287         reset_async
12288         return 0
12289 }
12290 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12291
12292 test_118h() {
12293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12294         remote_ost_nodsh && skip "remote OST with nodsh"
12295
12296         reset_async
12297
12298         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12299         set_nodes_failloc "$(osts_nodes)" 0x20e
12300         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12301         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12302         RC=$?
12303
12304         set_nodes_failloc "$(osts_nodes)" 0
12305         if [[ $RC -eq 0 ]]; then
12306                 error "Must return error due to dropped pages, rc=$RC"
12307         fi
12308
12309         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12310         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12311         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12312                     grep -c writeback)
12313         if [[ $LOCKED -ne 0 ]]; then
12314                 error "Locked pages remain in cache, locked=$LOCKED"
12315         fi
12316
12317         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12318                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12319         fi
12320
12321         rm -f $DIR/$tfile
12322         echo "No pages locked after fsync"
12323
12324         return 0
12325 }
12326 run_test 118h "Verify timeout in handling recoverables errors  =========="
12327
12328 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12329
12330 test_118i() {
12331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12332         remote_ost_nodsh && skip "remote OST with nodsh"
12333
12334         reset_async
12335
12336         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12337         set_nodes_failloc "$(osts_nodes)" 0x20e
12338
12339         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12340         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12341         PID=$!
12342         sleep 5
12343         set_nodes_failloc "$(osts_nodes)" 0
12344
12345         wait $PID
12346         RC=$?
12347         if [[ $RC -ne 0 ]]; then
12348                 error "got error, but should be not, rc=$RC"
12349         fi
12350
12351         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12352         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12353         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12354         if [[ $LOCKED -ne 0 ]]; then
12355                 error "Locked pages remain in cache, locked=$LOCKED"
12356         fi
12357
12358         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12359                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12360         fi
12361
12362         rm -f $DIR/$tfile
12363         echo "No pages locked after fsync"
12364
12365         return 0
12366 }
12367 run_test 118i "Fix error before timeout in recoverable error  =========="
12368
12369 [ "$SLOW" = "no" ] && set_resend_count 4
12370
12371 test_118j() {
12372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12373         remote_ost_nodsh && skip "remote OST with nodsh"
12374
12375         reset_async
12376
12377         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12378         set_nodes_failloc "$(osts_nodes)" 0x220
12379
12380         # return -EIO from OST
12381         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12382         RC=$?
12383         set_nodes_failloc "$(osts_nodes)" 0x0
12384         if [[ $RC -eq 0 ]]; then
12385                 error "Must return error due to dropped pages, rc=$RC"
12386         fi
12387
12388         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12389         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12390         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12391         if [[ $LOCKED -ne 0 ]]; then
12392                 error "Locked pages remain in cache, locked=$LOCKED"
12393         fi
12394
12395         # in recoverable error on OST we want resend and stay until it finished
12396         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12397                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12398         fi
12399
12400         rm -f $DIR/$tfile
12401         echo "No pages locked after fsync"
12402
12403         return 0
12404 }
12405 run_test 118j "Simulate unrecoverable OST side error =========="
12406
12407 test_118k()
12408 {
12409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12410         remote_ost_nodsh && skip "remote OSTs with nodsh"
12411
12412         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12413         set_nodes_failloc "$(osts_nodes)" 0x20e
12414         test_mkdir $DIR/$tdir
12415
12416         for ((i=0;i<10;i++)); do
12417                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12418                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12419                 SLEEPPID=$!
12420                 sleep 0.500s
12421                 kill $SLEEPPID
12422                 wait $SLEEPPID
12423         done
12424
12425         set_nodes_failloc "$(osts_nodes)" 0
12426         rm -rf $DIR/$tdir
12427 }
12428 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12429
12430 test_118l() # LU-646
12431 {
12432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12433
12434         test_mkdir $DIR/$tdir
12435         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12436         rm -rf $DIR/$tdir
12437 }
12438 run_test 118l "fsync dir"
12439
12440 test_118m() # LU-3066
12441 {
12442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12443
12444         test_mkdir $DIR/$tdir
12445         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12446         rm -rf $DIR/$tdir
12447 }
12448 run_test 118m "fdatasync dir ========="
12449
12450 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12451
12452 test_118n()
12453 {
12454         local begin
12455         local end
12456
12457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12458         remote_ost_nodsh && skip "remote OSTs with nodsh"
12459
12460         # Sleep to avoid a cached response.
12461         #define OBD_STATFS_CACHE_SECONDS 1
12462         sleep 2
12463
12464         # Inject a 10 second delay in the OST_STATFS handler.
12465         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12466         set_nodes_failloc "$(osts_nodes)" 0x242
12467
12468         begin=$SECONDS
12469         stat --file-system $MOUNT > /dev/null
12470         end=$SECONDS
12471
12472         set_nodes_failloc "$(osts_nodes)" 0
12473
12474         if ((end - begin > 20)); then
12475             error "statfs took $((end - begin)) seconds, expected 10"
12476         fi
12477 }
12478 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12479
12480 test_119a() # bug 11737
12481 {
12482         BSIZE=$((512 * 1024))
12483         directio write $DIR/$tfile 0 1 $BSIZE
12484         # We ask to read two blocks, which is more than a file size.
12485         # directio will indicate an error when requested and actual
12486         # sizes aren't equeal (a normal situation in this case) and
12487         # print actual read amount.
12488         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12489         if [ "$NOB" != "$BSIZE" ]; then
12490                 error "read $NOB bytes instead of $BSIZE"
12491         fi
12492         rm -f $DIR/$tfile
12493 }
12494 run_test 119a "Short directIO read must return actual read amount"
12495
12496 test_119b() # bug 11737
12497 {
12498         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12499
12500         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12501         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12502         sync
12503         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12504                 error "direct read failed"
12505         rm -f $DIR/$tfile
12506 }
12507 run_test 119b "Sparse directIO read must return actual read amount"
12508
12509 test_119c() # bug 13099
12510 {
12511         BSIZE=1048576
12512         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12513         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12514         rm -f $DIR/$tfile
12515 }
12516 run_test 119c "Testing for direct read hitting hole"
12517
12518 test_119d() # bug 15950
12519 {
12520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12521
12522         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12523         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12524         BSIZE=1048576
12525         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12526         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12527         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12528         lctl set_param fail_loc=0x40d
12529         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12530         pid_dio=$!
12531         sleep 1
12532         cat $DIR/$tfile > /dev/null &
12533         lctl set_param fail_loc=0
12534         pid_reads=$!
12535         wait $pid_dio
12536         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12537         sleep 2
12538         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12539         error "the read rpcs have not completed in 2s"
12540         rm -f $DIR/$tfile
12541         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12542 }
12543 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12544
12545 test_120a() {
12546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12547         remote_mds_nodsh && skip "remote MDS with nodsh"
12548         test_mkdir -i0 -c1 $DIR/$tdir
12549         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12550                 skip_env "no early lock cancel on server"
12551
12552         lru_resize_disable mdc
12553         lru_resize_disable osc
12554         cancel_lru_locks mdc
12555         # asynchronous object destroy at MDT could cause bl ast to client
12556         cancel_lru_locks osc
12557
12558         stat $DIR/$tdir > /dev/null
12559         can1=$(do_facet mds1 \
12560                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12561                awk '/ldlm_cancel/ {print $2}')
12562         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12563                awk '/ldlm_bl_callback/ {print $2}')
12564         test_mkdir -i0 -c1 $DIR/$tdir/d1
12565         can2=$(do_facet mds1 \
12566                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12567                awk '/ldlm_cancel/ {print $2}')
12568         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12569                awk '/ldlm_bl_callback/ {print $2}')
12570         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12571         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12572         lru_resize_enable mdc
12573         lru_resize_enable osc
12574 }
12575 run_test 120a "Early Lock Cancel: mkdir test"
12576
12577 test_120b() {
12578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12579         remote_mds_nodsh && skip "remote MDS with nodsh"
12580         test_mkdir $DIR/$tdir
12581         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12582                 skip_env "no early lock cancel on server"
12583
12584         lru_resize_disable mdc
12585         lru_resize_disable osc
12586         cancel_lru_locks mdc
12587         stat $DIR/$tdir > /dev/null
12588         can1=$(do_facet $SINGLEMDS \
12589                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12590                awk '/ldlm_cancel/ {print $2}')
12591         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12592                awk '/ldlm_bl_callback/ {print $2}')
12593         touch $DIR/$tdir/f1
12594         can2=$(do_facet $SINGLEMDS \
12595                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12596                awk '/ldlm_cancel/ {print $2}')
12597         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12598                awk '/ldlm_bl_callback/ {print $2}')
12599         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12600         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12601         lru_resize_enable mdc
12602         lru_resize_enable osc
12603 }
12604 run_test 120b "Early Lock Cancel: create test"
12605
12606 test_120c() {
12607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12608         remote_mds_nodsh && skip "remote MDS with nodsh"
12609         test_mkdir -i0 -c1 $DIR/$tdir
12610         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12611                 skip "no early lock cancel on server"
12612
12613         lru_resize_disable mdc
12614         lru_resize_disable osc
12615         test_mkdir -i0 -c1 $DIR/$tdir/d1
12616         test_mkdir -i0 -c1 $DIR/$tdir/d2
12617         touch $DIR/$tdir/d1/f1
12618         cancel_lru_locks mdc
12619         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12620         can1=$(do_facet mds1 \
12621                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12622                awk '/ldlm_cancel/ {print $2}')
12623         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12624                awk '/ldlm_bl_callback/ {print $2}')
12625         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12626         can2=$(do_facet mds1 \
12627                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12628                awk '/ldlm_cancel/ {print $2}')
12629         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12630                awk '/ldlm_bl_callback/ {print $2}')
12631         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12632         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12633         lru_resize_enable mdc
12634         lru_resize_enable osc
12635 }
12636 run_test 120c "Early Lock Cancel: link test"
12637
12638 test_120d() {
12639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12640         remote_mds_nodsh && skip "remote MDS with nodsh"
12641         test_mkdir -i0 -c1 $DIR/$tdir
12642         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12643                 skip_env "no early lock cancel on server"
12644
12645         lru_resize_disable mdc
12646         lru_resize_disable osc
12647         touch $DIR/$tdir
12648         cancel_lru_locks mdc
12649         stat $DIR/$tdir > /dev/null
12650         can1=$(do_facet mds1 \
12651                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12652                awk '/ldlm_cancel/ {print $2}')
12653         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12654                awk '/ldlm_bl_callback/ {print $2}')
12655         chmod a+x $DIR/$tdir
12656         can2=$(do_facet mds1 \
12657                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12658                awk '/ldlm_cancel/ {print $2}')
12659         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12660                awk '/ldlm_bl_callback/ {print $2}')
12661         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12662         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12663         lru_resize_enable mdc
12664         lru_resize_enable osc
12665 }
12666 run_test 120d "Early Lock Cancel: setattr test"
12667
12668 test_120e() {
12669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12670         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12671                 skip_env "no early lock cancel on server"
12672         remote_mds_nodsh && skip "remote MDS with nodsh"
12673
12674         local dlmtrace_set=false
12675
12676         test_mkdir -i0 -c1 $DIR/$tdir
12677         lru_resize_disable mdc
12678         lru_resize_disable osc
12679         ! $LCTL get_param debug | grep -q dlmtrace &&
12680                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12681         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12682         cancel_lru_locks mdc
12683         cancel_lru_locks osc
12684         dd if=$DIR/$tdir/f1 of=/dev/null
12685         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12686         # XXX client can not do early lock cancel of OST lock
12687         # during unlink (LU-4206), so cancel osc lock now.
12688         sleep 2
12689         cancel_lru_locks osc
12690         can1=$(do_facet mds1 \
12691                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12692                awk '/ldlm_cancel/ {print $2}')
12693         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12694                awk '/ldlm_bl_callback/ {print $2}')
12695         unlink $DIR/$tdir/f1
12696         sleep 5
12697         can2=$(do_facet mds1 \
12698                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12699                awk '/ldlm_cancel/ {print $2}')
12700         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12701                awk '/ldlm_bl_callback/ {print $2}')
12702         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12703                 $LCTL dk $TMP/cancel.debug.txt
12704         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12705                 $LCTL dk $TMP/blocking.debug.txt
12706         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12707         lru_resize_enable mdc
12708         lru_resize_enable osc
12709 }
12710 run_test 120e "Early Lock Cancel: unlink test"
12711
12712 test_120f() {
12713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12714         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12715                 skip_env "no early lock cancel on server"
12716         remote_mds_nodsh && skip "remote MDS with nodsh"
12717
12718         test_mkdir -i0 -c1 $DIR/$tdir
12719         lru_resize_disable mdc
12720         lru_resize_disable osc
12721         test_mkdir -i0 -c1 $DIR/$tdir/d1
12722         test_mkdir -i0 -c1 $DIR/$tdir/d2
12723         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12724         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12725         cancel_lru_locks mdc
12726         cancel_lru_locks osc
12727         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12728         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12729         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12730         # XXX client can not do early lock cancel of OST lock
12731         # during rename (LU-4206), so cancel osc lock now.
12732         sleep 2
12733         cancel_lru_locks osc
12734         can1=$(do_facet mds1 \
12735                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12736                awk '/ldlm_cancel/ {print $2}')
12737         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12738                awk '/ldlm_bl_callback/ {print $2}')
12739         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12740         sleep 5
12741         can2=$(do_facet mds1 \
12742                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12743                awk '/ldlm_cancel/ {print $2}')
12744         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12745                awk '/ldlm_bl_callback/ {print $2}')
12746         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12747         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12748         lru_resize_enable mdc
12749         lru_resize_enable osc
12750 }
12751 run_test 120f "Early Lock Cancel: rename test"
12752
12753 test_120g() {
12754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12755         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12756                 skip_env "no early lock cancel on server"
12757         remote_mds_nodsh && skip "remote MDS with nodsh"
12758
12759         lru_resize_disable mdc
12760         lru_resize_disable osc
12761         count=10000
12762         echo create $count files
12763         test_mkdir $DIR/$tdir
12764         cancel_lru_locks mdc
12765         cancel_lru_locks osc
12766         t0=$(date +%s)
12767
12768         can0=$(do_facet $SINGLEMDS \
12769                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12770                awk '/ldlm_cancel/ {print $2}')
12771         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12772                awk '/ldlm_bl_callback/ {print $2}')
12773         createmany -o $DIR/$tdir/f $count
12774         sync
12775         can1=$(do_facet $SINGLEMDS \
12776                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12777                awk '/ldlm_cancel/ {print $2}')
12778         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12779                awk '/ldlm_bl_callback/ {print $2}')
12780         t1=$(date +%s)
12781         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12782         echo rm $count files
12783         rm -r $DIR/$tdir
12784         sync
12785         can2=$(do_facet $SINGLEMDS \
12786                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12787                awk '/ldlm_cancel/ {print $2}')
12788         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12789                awk '/ldlm_bl_callback/ {print $2}')
12790         t2=$(date +%s)
12791         echo total: $count removes in $((t2-t1))
12792         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12793         sleep 2
12794         # wait for commitment of removal
12795         lru_resize_enable mdc
12796         lru_resize_enable osc
12797 }
12798 run_test 120g "Early Lock Cancel: performance test"
12799
12800 test_121() { #bug #10589
12801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12802
12803         rm -rf $DIR/$tfile
12804         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12805 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12806         lctl set_param fail_loc=0x310
12807         cancel_lru_locks osc > /dev/null
12808         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12809         lctl set_param fail_loc=0
12810         [[ $reads -eq $writes ]] ||
12811                 error "read $reads blocks, must be $writes blocks"
12812 }
12813 run_test 121 "read cancel race ========="
12814
12815 test_123a_base() { # was test 123, statahead(bug 11401)
12816         local lsx="$1"
12817
12818         SLOWOK=0
12819         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12820                 log "testing UP system. Performance may be lower than expected."
12821                 SLOWOK=1
12822         fi
12823
12824         rm -rf $DIR/$tdir
12825         test_mkdir $DIR/$tdir
12826         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12827         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12828         MULT=10
12829         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12830                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12831
12832                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12833                 lctl set_param -n llite.*.statahead_max 0
12834                 lctl get_param llite.*.statahead_max
12835                 cancel_lru_locks mdc
12836                 cancel_lru_locks osc
12837                 stime=$(date +%s)
12838                 time $lsx $DIR/$tdir | wc -l
12839                 etime=$(date +%s)
12840                 delta=$((etime - stime))
12841                 log "$lsx $i files without statahead: $delta sec"
12842                 lctl set_param llite.*.statahead_max=$max
12843
12844                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12845                         grep "statahead wrong:" | awk '{print $3}')
12846                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12847                 cancel_lru_locks mdc
12848                 cancel_lru_locks osc
12849                 stime=$(date +%s)
12850                 time $lsx $DIR/$tdir | wc -l
12851                 etime=$(date +%s)
12852                 delta_sa=$((etime - stime))
12853                 log "$lsx $i files with statahead: $delta_sa sec"
12854                 lctl get_param -n llite.*.statahead_stats
12855                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12856                         grep "statahead wrong:" | awk '{print $3}')
12857
12858                 [[ $swrong -lt $ewrong ]] &&
12859                         log "statahead was stopped, maybe too many locks held!"
12860                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12861
12862                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12863                         max=$(lctl get_param -n llite.*.statahead_max |
12864                                 head -n 1)
12865                         lctl set_param -n llite.*.statahead_max 0
12866                         lctl get_param llite.*.statahead_max
12867                         cancel_lru_locks mdc
12868                         cancel_lru_locks osc
12869                         stime=$(date +%s)
12870                         time $lsx $DIR/$tdir | wc -l
12871                         etime=$(date +%s)
12872                         delta=$((etime - stime))
12873                         log "$lsx $i files again without statahead: $delta sec"
12874                         lctl set_param llite.*.statahead_max=$max
12875                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12876                                 if [  $SLOWOK -eq 0 ]; then
12877                                         error "$lsx $i files is slower with statahead!"
12878                                 else
12879                                         log "$lsx $i files is slower with statahead!"
12880                                 fi
12881                                 break
12882                         fi
12883                 fi
12884
12885                 [ $delta -gt 20 ] && break
12886                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12887                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12888         done
12889         log "$lsx done"
12890
12891         stime=$(date +%s)
12892         rm -r $DIR/$tdir
12893         sync
12894         etime=$(date +%s)
12895         delta=$((etime - stime))
12896         log "rm -r $DIR/$tdir/: $delta seconds"
12897         log "rm done"
12898         lctl get_param -n llite.*.statahead_stats
12899 }
12900
12901 test_123aa() {
12902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12903
12904         test_123a_base "ls -l"
12905 }
12906 run_test 123aa "verify statahead work"
12907
12908 test_123ab() {
12909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12910
12911         statx_supported || skip_env "Test must be statx() syscall supported"
12912
12913         test_123a_base "$STATX -l"
12914 }
12915 run_test 123ab "verify statahead work by using statx"
12916
12917 test_123ac() {
12918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12919
12920         statx_supported || skip_env "Test must be statx() syscall supported"
12921
12922         local rpcs_before
12923         local rpcs_after
12924         local agl_before
12925         local agl_after
12926
12927         cancel_lru_locks $OSC
12928         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12929         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12930                 awk '/agl.total:/ {print $3}')
12931         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12932         test_123a_base "$STATX --cached=always -D"
12933         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12934                 awk '/agl.total:/ {print $3}')
12935         [ $agl_before -eq $agl_after ] ||
12936                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12937         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12938         [ $rpcs_after -eq $rpcs_before ] ||
12939                 error "$STATX should not send glimpse RPCs to $OSC"
12940 }
12941 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12942
12943 test_123b () { # statahead(bug 15027)
12944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12945
12946         test_mkdir $DIR/$tdir
12947         createmany -o $DIR/$tdir/$tfile-%d 1000
12948
12949         cancel_lru_locks mdc
12950         cancel_lru_locks osc
12951
12952 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12953         lctl set_param fail_loc=0x80000803
12954         ls -lR $DIR/$tdir > /dev/null
12955         log "ls done"
12956         lctl set_param fail_loc=0x0
12957         lctl get_param -n llite.*.statahead_stats
12958         rm -r $DIR/$tdir
12959         sync
12960
12961 }
12962 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12963
12964 test_123c() {
12965         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12966
12967         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12968         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12969         touch $DIR/$tdir.1/{1..3}
12970         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12971
12972         remount_client $MOUNT
12973
12974         $MULTIOP $DIR/$tdir.0 Q
12975
12976         # let statahead to complete
12977         ls -l $DIR/$tdir.0 > /dev/null
12978
12979         testid=$(echo $TESTNAME | tr '_' ' ')
12980         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12981                 error "statahead warning" || true
12982 }
12983 run_test 123c "Can not initialize inode warning on DNE statahead"
12984
12985 test_124a() {
12986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12987         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12988                 skip_env "no lru resize on server"
12989
12990         local NR=2000
12991
12992         test_mkdir $DIR/$tdir
12993
12994         log "create $NR files at $DIR/$tdir"
12995         createmany -o $DIR/$tdir/f $NR ||
12996                 error "failed to create $NR files in $DIR/$tdir"
12997
12998         cancel_lru_locks mdc
12999         ls -l $DIR/$tdir > /dev/null
13000
13001         local NSDIR=""
13002         local LRU_SIZE=0
13003         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13004                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13005                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13006                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13007                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13008                         log "NSDIR=$NSDIR"
13009                         log "NS=$(basename $NSDIR)"
13010                         break
13011                 fi
13012         done
13013
13014         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13015                 skip "Not enough cached locks created!"
13016         fi
13017         log "LRU=$LRU_SIZE"
13018
13019         local SLEEP=30
13020
13021         # We know that lru resize allows one client to hold $LIMIT locks
13022         # for 10h. After that locks begin to be killed by client.
13023         local MAX_HRS=10
13024         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13025         log "LIMIT=$LIMIT"
13026         if [ $LIMIT -lt $LRU_SIZE ]; then
13027                 skip "Limit is too small $LIMIT"
13028         fi
13029
13030         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13031         # killing locks. Some time was spent for creating locks. This means
13032         # that up to the moment of sleep finish we must have killed some of
13033         # them (10-100 locks). This depends on how fast ther were created.
13034         # Many of them were touched in almost the same moment and thus will
13035         # be killed in groups.
13036         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13037
13038         # Use $LRU_SIZE_B here to take into account real number of locks
13039         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13040         local LRU_SIZE_B=$LRU_SIZE
13041         log "LVF=$LVF"
13042         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13043         log "OLD_LVF=$OLD_LVF"
13044         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13045
13046         # Let's make sure that we really have some margin. Client checks
13047         # cached locks every 10 sec.
13048         SLEEP=$((SLEEP+20))
13049         log "Sleep ${SLEEP} sec"
13050         local SEC=0
13051         while ((SEC<$SLEEP)); do
13052                 echo -n "..."
13053                 sleep 5
13054                 SEC=$((SEC+5))
13055                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13056                 echo -n "$LRU_SIZE"
13057         done
13058         echo ""
13059         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13060         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13061
13062         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13063                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13064                 unlinkmany $DIR/$tdir/f $NR
13065                 return
13066         }
13067
13068         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13069         log "unlink $NR files at $DIR/$tdir"
13070         unlinkmany $DIR/$tdir/f $NR
13071 }
13072 run_test 124a "lru resize ======================================="
13073
13074 get_max_pool_limit()
13075 {
13076         local limit=$($LCTL get_param \
13077                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13078         local max=0
13079         for l in $limit; do
13080                 if [[ $l -gt $max ]]; then
13081                         max=$l
13082                 fi
13083         done
13084         echo $max
13085 }
13086
13087 test_124b() {
13088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13089         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13090                 skip_env "no lru resize on server"
13091
13092         LIMIT=$(get_max_pool_limit)
13093
13094         NR=$(($(default_lru_size)*20))
13095         if [[ $NR -gt $LIMIT ]]; then
13096                 log "Limit lock number by $LIMIT locks"
13097                 NR=$LIMIT
13098         fi
13099
13100         IFree=$(mdsrate_inodes_available)
13101         if [ $IFree -lt $NR ]; then
13102                 log "Limit lock number by $IFree inodes"
13103                 NR=$IFree
13104         fi
13105
13106         lru_resize_disable mdc
13107         test_mkdir -p $DIR/$tdir/disable_lru_resize
13108
13109         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13110         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13111         cancel_lru_locks mdc
13112         stime=`date +%s`
13113         PID=""
13114         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13115         PID="$PID $!"
13116         sleep 2
13117         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13118         PID="$PID $!"
13119         sleep 2
13120         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13121         PID="$PID $!"
13122         wait $PID
13123         etime=`date +%s`
13124         nolruresize_delta=$((etime-stime))
13125         log "ls -la time: $nolruresize_delta seconds"
13126         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13127         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13128
13129         lru_resize_enable mdc
13130         test_mkdir -p $DIR/$tdir/enable_lru_resize
13131
13132         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13133         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13134         cancel_lru_locks mdc
13135         stime=`date +%s`
13136         PID=""
13137         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13138         PID="$PID $!"
13139         sleep 2
13140         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13141         PID="$PID $!"
13142         sleep 2
13143         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13144         PID="$PID $!"
13145         wait $PID
13146         etime=`date +%s`
13147         lruresize_delta=$((etime-stime))
13148         log "ls -la time: $lruresize_delta seconds"
13149         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13150
13151         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13152                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13153         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13154                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13155         else
13156                 log "lru resize performs the same with no lru resize"
13157         fi
13158         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13159 }
13160 run_test 124b "lru resize (performance test) ======================="
13161
13162 test_124c() {
13163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13164         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13165                 skip_env "no lru resize on server"
13166
13167         # cache ununsed locks on client
13168         local nr=100
13169         cancel_lru_locks mdc
13170         test_mkdir $DIR/$tdir
13171         createmany -o $DIR/$tdir/f $nr ||
13172                 error "failed to create $nr files in $DIR/$tdir"
13173         ls -l $DIR/$tdir > /dev/null
13174
13175         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13176         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13177         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13178         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13179         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13180
13181         # set lru_max_age to 1 sec
13182         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13183         echo "sleep $((recalc_p * 2)) seconds..."
13184         sleep $((recalc_p * 2))
13185
13186         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13187         # restore lru_max_age
13188         $LCTL set_param -n $nsdir.lru_max_age $max_age
13189         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13190         unlinkmany $DIR/$tdir/f $nr
13191 }
13192 run_test 124c "LRUR cancel very aged locks"
13193
13194 test_124d() {
13195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13196         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13197                 skip_env "no lru resize on server"
13198
13199         # cache ununsed locks on client
13200         local nr=100
13201
13202         lru_resize_disable mdc
13203         stack_trap "lru_resize_enable mdc" EXIT
13204
13205         cancel_lru_locks mdc
13206
13207         # asynchronous object destroy at MDT could cause bl ast to client
13208         test_mkdir $DIR/$tdir
13209         createmany -o $DIR/$tdir/f $nr ||
13210                 error "failed to create $nr files in $DIR/$tdir"
13211         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13212
13213         ls -l $DIR/$tdir > /dev/null
13214
13215         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13216         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13217         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13218         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13219
13220         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13221
13222         # set lru_max_age to 1 sec
13223         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13224         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13225
13226         echo "sleep $((recalc_p * 2)) seconds..."
13227         sleep $((recalc_p * 2))
13228
13229         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13230
13231         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13232 }
13233 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13234
13235 test_125() { # 13358
13236         $LCTL get_param -n llite.*.client_type | grep -q local ||
13237                 skip "must run as local client"
13238         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13239                 skip_env "must have acl enabled"
13240         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13241
13242         test_mkdir $DIR/$tdir
13243         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13244         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13245         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13246 }
13247 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13248
13249 test_126() { # bug 12829/13455
13250         $GSS && skip_env "must run as gss disabled"
13251         $LCTL get_param -n llite.*.client_type | grep -q local ||
13252                 skip "must run as local client"
13253         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13254
13255         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13256         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13257         rm -f $DIR/$tfile
13258         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13259 }
13260 run_test 126 "check that the fsgid provided by the client is taken into account"
13261
13262 test_127a() { # bug 15521
13263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13264         local name count samp unit min max sum sumsq
13265
13266         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13267         echo "stats before reset"
13268         $LCTL get_param osc.*.stats
13269         $LCTL set_param osc.*.stats=0
13270         local fsize=$((2048 * 1024))
13271
13272         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13273         cancel_lru_locks osc
13274         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13275
13276         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13277         stack_trap "rm -f $TMP/$tfile.tmp"
13278         while read name count samp unit min max sum sumsq; do
13279                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13280                 [ ! $min ] && error "Missing min value for $name proc entry"
13281                 eval $name=$count || error "Wrong proc format"
13282
13283                 case $name in
13284                 read_bytes|write_bytes)
13285                         [[ "$unit" =~ "bytes" ]] ||
13286                                 error "unit is not 'bytes': $unit"
13287                         (( $min >= 4096 )) || error "min is too small: $min"
13288                         (( $min <= $fsize )) || error "min is too big: $min"
13289                         (( $max >= 4096 )) || error "max is too small: $max"
13290                         (( $max <= $fsize )) || error "max is too big: $max"
13291                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13292                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13293                                 error "sumsquare is too small: $sumsq"
13294                         (( $sumsq <= $fsize * $fsize )) ||
13295                                 error "sumsquare is too big: $sumsq"
13296                         ;;
13297                 ost_read|ost_write)
13298                         [[ "$unit" =~ "usec" ]] ||
13299                                 error "unit is not 'usec': $unit"
13300                         ;;
13301                 *)      ;;
13302                 esac
13303         done < $DIR/$tfile.tmp
13304
13305         #check that we actually got some stats
13306         [ "$read_bytes" ] || error "Missing read_bytes stats"
13307         [ "$write_bytes" ] || error "Missing write_bytes stats"
13308         [ "$read_bytes" != 0 ] || error "no read done"
13309         [ "$write_bytes" != 0 ] || error "no write done"
13310 }
13311 run_test 127a "verify the client stats are sane"
13312
13313 test_127b() { # bug LU-333
13314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13315         local name count samp unit min max sum sumsq
13316
13317         echo "stats before reset"
13318         $LCTL get_param llite.*.stats
13319         $LCTL set_param llite.*.stats=0
13320
13321         # perform 2 reads and writes so MAX is different from SUM.
13322         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13323         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13324         cancel_lru_locks osc
13325         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13326         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13327
13328         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13329         stack_trap "rm -f $TMP/$tfile.tmp"
13330         while read name count samp unit min max sum sumsq; do
13331                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13332                 eval $name=$count || error "Wrong proc format"
13333
13334                 case $name in
13335                 read_bytes|write_bytes)
13336                         [[ "$unit" =~ "bytes" ]] ||
13337                                 error "unit is not 'bytes': $unit"
13338                         (( $count == 2 )) || error "count is not 2: $count"
13339                         (( $min == $PAGE_SIZE )) ||
13340                                 error "min is not $PAGE_SIZE: $min"
13341                         (( $max == $PAGE_SIZE )) ||
13342                                 error "max is not $PAGE_SIZE: $max"
13343                         (( $sum == $PAGE_SIZE * 2 )) ||
13344                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13345                         ;;
13346                 read|write)
13347                         [[ "$unit" =~ "usec" ]] ||
13348                                 error "unit is not 'usec': $unit"
13349                         ;;
13350                 *)      ;;
13351                 esac
13352         done < $TMP/$tfile.tmp
13353
13354         #check that we actually got some stats
13355         [ "$read_bytes" ] || error "Missing read_bytes stats"
13356         [ "$write_bytes" ] || error "Missing write_bytes stats"
13357         [ "$read_bytes" != 0 ] || error "no read done"
13358         [ "$write_bytes" != 0 ] || error "no write done"
13359 }
13360 run_test 127b "verify the llite client stats are sane"
13361
13362 test_127c() { # LU-12394
13363         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13364         local size
13365         local bsize
13366         local reads
13367         local writes
13368         local count
13369
13370         $LCTL set_param llite.*.extents_stats=1
13371         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13372
13373         # Use two stripes so there is enough space in default config
13374         $LFS setstripe -c 2 $DIR/$tfile
13375
13376         # Extent stats start at 0-4K and go in power of two buckets
13377         # LL_HIST_START = 12 --> 2^12 = 4K
13378         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13379         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13380         # small configs
13381         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13382                 do
13383                 # Write and read, 2x each, second time at a non-zero offset
13384                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13385                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13386                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13387                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13388                 rm -f $DIR/$tfile
13389         done
13390
13391         $LCTL get_param llite.*.extents_stats
13392
13393         count=2
13394         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13395                 do
13396                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13397                                 grep -m 1 $bsize)
13398                 reads=$(echo $bucket | awk '{print $5}')
13399                 writes=$(echo $bucket | awk '{print $9}')
13400                 [ "$reads" -eq $count ] ||
13401                         error "$reads reads in < $bsize bucket, expect $count"
13402                 [ "$writes" -eq $count ] ||
13403                         error "$writes writes in < $bsize bucket, expect $count"
13404         done
13405
13406         # Test mmap write and read
13407         $LCTL set_param llite.*.extents_stats=c
13408         size=512
13409         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13410         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13411         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13412
13413         $LCTL get_param llite.*.extents_stats
13414
13415         count=$(((size*1024) / PAGE_SIZE))
13416
13417         bsize=$((2 * PAGE_SIZE / 1024))K
13418
13419         bucket=$($LCTL get_param -n llite.*.extents_stats |
13420                         grep -m 1 $bsize)
13421         reads=$(echo $bucket | awk '{print $5}')
13422         writes=$(echo $bucket | awk '{print $9}')
13423         # mmap writes fault in the page first, creating an additonal read
13424         [ "$reads" -eq $((2 * count)) ] ||
13425                 error "$reads reads in < $bsize bucket, expect $count"
13426         [ "$writes" -eq $count ] ||
13427                 error "$writes writes in < $bsize bucket, expect $count"
13428 }
13429 run_test 127c "test llite extent stats with regular & mmap i/o"
13430
13431 test_128() { # bug 15212
13432         touch $DIR/$tfile
13433         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13434                 find $DIR/$tfile
13435                 find $DIR/$tfile
13436         EOF
13437
13438         result=$(grep error $TMP/$tfile.log)
13439         rm -f $DIR/$tfile $TMP/$tfile.log
13440         [ -z "$result" ] ||
13441                 error "consecutive find's under interactive lfs failed"
13442 }
13443 run_test 128 "interactive lfs for 2 consecutive find's"
13444
13445 set_dir_limits () {
13446         local mntdev
13447         local canondev
13448         local node
13449
13450         local ldproc=/proc/fs/ldiskfs
13451         local facets=$(get_facets MDS)
13452
13453         for facet in ${facets//,/ }; do
13454                 canondev=$(ldiskfs_canon \
13455                            *.$(convert_facet2label $facet).mntdev $facet)
13456                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13457                         ldproc=/sys/fs/ldiskfs
13458                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13459                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13460         done
13461 }
13462
13463 check_mds_dmesg() {
13464         local facets=$(get_facets MDS)
13465         for facet in ${facets//,/ }; do
13466                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13467         done
13468         return 1
13469 }
13470
13471 test_129() {
13472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13473         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13474                 skip "Need MDS version with at least 2.5.56"
13475         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13476                 skip_env "ldiskfs only test"
13477         fi
13478         remote_mds_nodsh && skip "remote MDS with nodsh"
13479
13480         local ENOSPC=28
13481         local has_warning=false
13482
13483         rm -rf $DIR/$tdir
13484         mkdir -p $DIR/$tdir
13485
13486         # block size of mds1
13487         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13488         set_dir_limits $maxsize $((maxsize * 6 / 8))
13489         stack_trap "set_dir_limits 0 0"
13490         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13491         local dirsize=$(stat -c%s "$DIR/$tdir")
13492         local nfiles=0
13493         while (( $dirsize <= $maxsize )); do
13494                 $MCREATE $DIR/$tdir/file_base_$nfiles
13495                 rc=$?
13496                 # check two errors:
13497                 # ENOSPC for ext4 max_dir_size, which has been used since
13498                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13499                 if (( rc == ENOSPC )); then
13500                         set_dir_limits 0 0
13501                         echo "rc=$rc returned as expected after $nfiles files"
13502
13503                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13504                                 error "create failed w/o dir size limit"
13505
13506                         # messages may be rate limited if test is run repeatedly
13507                         check_mds_dmesg '"is approaching max"' ||
13508                                 echo "warning message should be output"
13509                         check_mds_dmesg '"has reached max"' ||
13510                                 echo "reached message should be output"
13511
13512                         dirsize=$(stat -c%s "$DIR/$tdir")
13513
13514                         [[ $dirsize -ge $maxsize ]] && return 0
13515                         error "dirsize $dirsize < $maxsize after $nfiles files"
13516                 elif (( rc != 0 )); then
13517                         break
13518                 fi
13519                 nfiles=$((nfiles + 1))
13520                 dirsize=$(stat -c%s "$DIR/$tdir")
13521         done
13522
13523         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13524 }
13525 run_test 129 "test directory size limit ========================"
13526
13527 OLDIFS="$IFS"
13528 cleanup_130() {
13529         trap 0
13530         IFS="$OLDIFS"
13531 }
13532
13533 test_130a() {
13534         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13535         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13536
13537         trap cleanup_130 EXIT RETURN
13538
13539         local fm_file=$DIR/$tfile
13540         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13541         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13542                 error "dd failed for $fm_file"
13543
13544         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13545         filefrag -ves $fm_file
13546         RC=$?
13547         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13548                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13549         [ $RC != 0 ] && error "filefrag $fm_file failed"
13550
13551         filefrag_op=$(filefrag -ve -k $fm_file |
13552                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13553         lun=$($LFS getstripe -i $fm_file)
13554
13555         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13556         IFS=$'\n'
13557         tot_len=0
13558         for line in $filefrag_op
13559         do
13560                 frag_lun=`echo $line | cut -d: -f5`
13561                 ext_len=`echo $line | cut -d: -f4`
13562                 if (( $frag_lun != $lun )); then
13563                         cleanup_130
13564                         error "FIEMAP on 1-stripe file($fm_file) failed"
13565                         return
13566                 fi
13567                 (( tot_len += ext_len ))
13568         done
13569
13570         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13571                 cleanup_130
13572                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13573                 return
13574         fi
13575
13576         cleanup_130
13577
13578         echo "FIEMAP on single striped file succeeded"
13579 }
13580 run_test 130a "FIEMAP (1-stripe file)"
13581
13582 test_130b() {
13583         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13584
13585         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13586         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13587
13588         trap cleanup_130 EXIT RETURN
13589
13590         local fm_file=$DIR/$tfile
13591         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13592                         error "setstripe on $fm_file"
13593         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13594                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13595
13596         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13597                 error "dd failed on $fm_file"
13598
13599         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13600         filefrag_op=$(filefrag -ve -k $fm_file |
13601                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13602
13603         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13604                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13605
13606         IFS=$'\n'
13607         tot_len=0
13608         num_luns=1
13609         for line in $filefrag_op
13610         do
13611                 frag_lun=$(echo $line | cut -d: -f5 |
13612                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13613                 ext_len=$(echo $line | cut -d: -f4)
13614                 if (( $frag_lun != $last_lun )); then
13615                         if (( tot_len != 1024 )); then
13616                                 cleanup_130
13617                                 error "FIEMAP on $fm_file failed; returned " \
13618                                 "len $tot_len for OST $last_lun instead of 1024"
13619                                 return
13620                         else
13621                                 (( num_luns += 1 ))
13622                                 tot_len=0
13623                         fi
13624                 fi
13625                 (( tot_len += ext_len ))
13626                 last_lun=$frag_lun
13627         done
13628         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13629                 cleanup_130
13630                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13631                         "luns or wrong len for OST $last_lun"
13632                 return
13633         fi
13634
13635         cleanup_130
13636
13637         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13638 }
13639 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13640
13641 test_130c() {
13642         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13643
13644         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13645         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13646
13647         trap cleanup_130 EXIT RETURN
13648
13649         local fm_file=$DIR/$tfile
13650         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13651         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13652                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13653
13654         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13655                         error "dd failed on $fm_file"
13656
13657         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13658         filefrag_op=$(filefrag -ve -k $fm_file |
13659                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13660
13661         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13662                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13663
13664         IFS=$'\n'
13665         tot_len=0
13666         num_luns=1
13667         for line in $filefrag_op
13668         do
13669                 frag_lun=$(echo $line | cut -d: -f5 |
13670                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13671                 ext_len=$(echo $line | cut -d: -f4)
13672                 if (( $frag_lun != $last_lun )); then
13673                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13674                         if (( logical != 512 )); then
13675                                 cleanup_130
13676                                 error "FIEMAP on $fm_file failed; returned " \
13677                                 "logical start for lun $logical instead of 512"
13678                                 return
13679                         fi
13680                         if (( tot_len != 512 )); then
13681                                 cleanup_130
13682                                 error "FIEMAP on $fm_file failed; returned " \
13683                                 "len $tot_len for OST $last_lun instead of 1024"
13684                                 return
13685                         else
13686                                 (( num_luns += 1 ))
13687                                 tot_len=0
13688                         fi
13689                 fi
13690                 (( tot_len += ext_len ))
13691                 last_lun=$frag_lun
13692         done
13693         if (( num_luns != 2 || tot_len != 512 )); then
13694                 cleanup_130
13695                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13696                         "luns or wrong len for OST $last_lun"
13697                 return
13698         fi
13699
13700         cleanup_130
13701
13702         echo "FIEMAP on 2-stripe file with hole succeeded"
13703 }
13704 run_test 130c "FIEMAP (2-stripe file with hole)"
13705
13706 test_130d() {
13707         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13708
13709         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13710         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13711
13712         trap cleanup_130 EXIT RETURN
13713
13714         local fm_file=$DIR/$tfile
13715         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13716                         error "setstripe on $fm_file"
13717         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13718                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13719
13720         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13721         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13722                 error "dd failed on $fm_file"
13723
13724         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13725         filefrag_op=$(filefrag -ve -k $fm_file |
13726                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13727
13728         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13729                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13730
13731         IFS=$'\n'
13732         tot_len=0
13733         num_luns=1
13734         for line in $filefrag_op
13735         do
13736                 frag_lun=$(echo $line | cut -d: -f5 |
13737                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13738                 ext_len=$(echo $line | cut -d: -f4)
13739                 if (( $frag_lun != $last_lun )); then
13740                         if (( tot_len != 1024 )); then
13741                                 cleanup_130
13742                                 error "FIEMAP on $fm_file failed; returned " \
13743                                 "len $tot_len for OST $last_lun instead of 1024"
13744                                 return
13745                         else
13746                                 (( num_luns += 1 ))
13747                                 tot_len=0
13748                         fi
13749                 fi
13750                 (( tot_len += ext_len ))
13751                 last_lun=$frag_lun
13752         done
13753         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13754                 cleanup_130
13755                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13756                         "luns or wrong len for OST $last_lun"
13757                 return
13758         fi
13759
13760         cleanup_130
13761
13762         echo "FIEMAP on N-stripe file succeeded"
13763 }
13764 run_test 130d "FIEMAP (N-stripe file)"
13765
13766 test_130e() {
13767         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13768
13769         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13770         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13771
13772         trap cleanup_130 EXIT RETURN
13773
13774         local fm_file=$DIR/$tfile
13775         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13776
13777         NUM_BLKS=512
13778         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13779         for ((i = 0; i < $NUM_BLKS; i++)); do
13780                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13781                         conv=notrunc > /dev/null 2>&1
13782         done
13783
13784         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13785         filefrag_op=$(filefrag -ve -k $fm_file |
13786                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13787
13788         last_lun=$(echo $filefrag_op | cut -d: -f5)
13789
13790         IFS=$'\n'
13791         tot_len=0
13792         num_luns=1
13793         for line in $filefrag_op; do
13794                 frag_lun=$(echo $line | cut -d: -f5)
13795                 ext_len=$(echo $line | cut -d: -f4)
13796                 if [[ "$frag_lun" != "$last_lun" ]]; then
13797                         if (( tot_len != $EXPECTED_LEN )); then
13798                                 cleanup_130
13799                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13800                         else
13801                                 (( num_luns += 1 ))
13802                                 tot_len=0
13803                         fi
13804                 fi
13805                 (( tot_len += ext_len ))
13806                 last_lun=$frag_lun
13807         done
13808         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13809                 cleanup_130
13810                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13811         fi
13812
13813         echo "FIEMAP with continuation calls succeeded"
13814 }
13815 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13816
13817 test_130f() {
13818         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13819         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13820
13821         local fm_file=$DIR/$tfile
13822         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13823                 error "multiop create with lov_delay_create on $fm_file"
13824
13825         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13826         filefrag_extents=$(filefrag -vek $fm_file |
13827                            awk '/extents? found/ { print $2 }')
13828         if [[ "$filefrag_extents" != "0" ]]; then
13829                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13830         fi
13831
13832         rm -f $fm_file
13833 }
13834 run_test 130f "FIEMAP (unstriped file)"
13835
13836 test_130g() {
13837         local file=$DIR/$tfile
13838         local nr=$((OSTCOUNT * 100))
13839
13840         $LFS setstripe -C $nr $file ||
13841                 error "failed to setstripe -C $nr $file"
13842
13843         dd if=/dev/zero of=$file count=$nr bs=1M
13844         sync
13845         nr=$($LFS getstripe -c $file)
13846
13847         local extents=$(filefrag -v $file |
13848                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13849
13850         echo "filefrag list $extents extents in file with stripecount $nr"
13851         if (( extents < nr )); then
13852                 $LFS getstripe $file
13853                 filefrag -v $file
13854                 error "filefrag printed $extents < $nr extents"
13855         fi
13856
13857         rm -f $file
13858 }
13859 run_test 130g "FIEMAP (overstripe file)"
13860
13861 # Test for writev/readv
13862 test_131a() {
13863         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13864                 error "writev test failed"
13865         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13866                 error "readv failed"
13867         rm -f $DIR/$tfile
13868 }
13869 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13870
13871 test_131b() {
13872         local fsize=$((524288 + 1048576 + 1572864))
13873         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13874                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13875                         error "append writev test failed"
13876
13877         ((fsize += 1572864 + 1048576))
13878         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13879                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13880                         error "append writev test failed"
13881         rm -f $DIR/$tfile
13882 }
13883 run_test 131b "test append writev"
13884
13885 test_131c() {
13886         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13887         error "NOT PASS"
13888 }
13889 run_test 131c "test read/write on file w/o objects"
13890
13891 test_131d() {
13892         rwv -f $DIR/$tfile -w -n 1 1572864
13893         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13894         if [ "$NOB" != 1572864 ]; then
13895                 error "Short read filed: read $NOB bytes instead of 1572864"
13896         fi
13897         rm -f $DIR/$tfile
13898 }
13899 run_test 131d "test short read"
13900
13901 test_131e() {
13902         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13903         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13904         error "read hitting hole failed"
13905         rm -f $DIR/$tfile
13906 }
13907 run_test 131e "test read hitting hole"
13908
13909 check_stats() {
13910         local facet=$1
13911         local op=$2
13912         local want=${3:-0}
13913         local res
13914
13915         case $facet in
13916         mds*) res=$(do_facet $facet \
13917                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13918                  ;;
13919         ost*) res=$(do_facet $facet \
13920                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13921                  ;;
13922         *) error "Wrong facet '$facet'" ;;
13923         esac
13924         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13925         # if the argument $3 is zero, it means any stat increment is ok.
13926         if [[ $want -gt 0 ]]; then
13927                 local count=$(echo $res | awk '{ print $2 }')
13928                 [[ $count -ne $want ]] &&
13929                         error "The $op counter on $facet is $count, not $want"
13930         fi
13931 }
13932
13933 test_133a() {
13934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13935         remote_ost_nodsh && skip "remote OST with nodsh"
13936         remote_mds_nodsh && skip "remote MDS with nodsh"
13937         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13938                 skip_env "MDS doesn't support rename stats"
13939
13940         local testdir=$DIR/${tdir}/stats_testdir
13941
13942         mkdir -p $DIR/${tdir}
13943
13944         # clear stats.
13945         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13946         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13947
13948         # verify mdt stats first.
13949         mkdir ${testdir} || error "mkdir failed"
13950         check_stats $SINGLEMDS "mkdir" 1
13951         touch ${testdir}/${tfile} || error "touch failed"
13952         check_stats $SINGLEMDS "open" 1
13953         check_stats $SINGLEMDS "close" 1
13954         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13955                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13956                 check_stats $SINGLEMDS "mknod" 2
13957         }
13958         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13959         check_stats $SINGLEMDS "unlink" 1
13960         rm -f ${testdir}/${tfile} || error "file remove failed"
13961         check_stats $SINGLEMDS "unlink" 2
13962
13963         # remove working dir and check mdt stats again.
13964         rmdir ${testdir} || error "rmdir failed"
13965         check_stats $SINGLEMDS "rmdir" 1
13966
13967         local testdir1=$DIR/${tdir}/stats_testdir1
13968         mkdir -p ${testdir}
13969         mkdir -p ${testdir1}
13970         touch ${testdir1}/test1
13971         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13972         check_stats $SINGLEMDS "crossdir_rename" 1
13973
13974         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13975         check_stats $SINGLEMDS "samedir_rename" 1
13976
13977         rm -rf $DIR/${tdir}
13978 }
13979 run_test 133a "Verifying MDT stats ========================================"
13980
13981 test_133b() {
13982         local res
13983
13984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13985         remote_ost_nodsh && skip "remote OST with nodsh"
13986         remote_mds_nodsh && skip "remote MDS with nodsh"
13987
13988         local testdir=$DIR/${tdir}/stats_testdir
13989
13990         mkdir -p ${testdir} || error "mkdir failed"
13991         touch ${testdir}/${tfile} || error "touch failed"
13992         cancel_lru_locks mdc
13993
13994         # clear stats.
13995         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13996         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13997
13998         # extra mdt stats verification.
13999         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14000         check_stats $SINGLEMDS "setattr" 1
14001         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14002         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14003         then            # LU-1740
14004                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14005                 check_stats $SINGLEMDS "getattr" 1
14006         fi
14007         rm -rf $DIR/${tdir}
14008
14009         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14010         # so the check below is not reliable
14011         [ $MDSCOUNT -eq 1 ] || return 0
14012
14013         # Sleep to avoid a cached response.
14014         #define OBD_STATFS_CACHE_SECONDS 1
14015         sleep 2
14016         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14017         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14018         $LFS df || error "lfs failed"
14019         check_stats $SINGLEMDS "statfs" 1
14020
14021         # check aggregated statfs (LU-10018)
14022         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14023                 return 0
14024         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14025                 return 0
14026         sleep 2
14027         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14028         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14029         df $DIR
14030         check_stats $SINGLEMDS "statfs" 1
14031
14032         # We want to check that the client didn't send OST_STATFS to
14033         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14034         # extra care is needed here.
14035         if remote_mds; then
14036                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14037                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14038
14039                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14040                 [ "$res" ] && error "OST got STATFS"
14041         fi
14042
14043         return 0
14044 }
14045 run_test 133b "Verifying extra MDT stats =================================="
14046
14047 test_133c() {
14048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14049         remote_ost_nodsh && skip "remote OST with nodsh"
14050         remote_mds_nodsh && skip "remote MDS with nodsh"
14051
14052         local testdir=$DIR/$tdir/stats_testdir
14053
14054         test_mkdir -p $testdir
14055
14056         # verify obdfilter stats.
14057         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14058         sync
14059         cancel_lru_locks osc
14060         wait_delete_completed
14061
14062         # clear stats.
14063         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14064         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14065
14066         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14067                 error "dd failed"
14068         sync
14069         cancel_lru_locks osc
14070         check_stats ost1 "write" 1
14071
14072         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14073         check_stats ost1 "read" 1
14074
14075         > $testdir/$tfile || error "truncate failed"
14076         check_stats ost1 "punch" 1
14077
14078         rm -f $testdir/$tfile || error "file remove failed"
14079         wait_delete_completed
14080         check_stats ost1 "destroy" 1
14081
14082         rm -rf $DIR/$tdir
14083 }
14084 run_test 133c "Verifying OST stats ========================================"
14085
14086 order_2() {
14087         local value=$1
14088         local orig=$value
14089         local order=1
14090
14091         while [ $value -ge 2 ]; do
14092                 order=$((order*2))
14093                 value=$((value/2))
14094         done
14095
14096         if [ $orig -gt $order ]; then
14097                 order=$((order*2))
14098         fi
14099         echo $order
14100 }
14101
14102 size_in_KMGT() {
14103     local value=$1
14104     local size=('K' 'M' 'G' 'T');
14105     local i=0
14106     local size_string=$value
14107
14108     while [ $value -ge 1024 ]; do
14109         if [ $i -gt 3 ]; then
14110             #T is the biggest unit we get here, if that is bigger,
14111             #just return XXXT
14112             size_string=${value}T
14113             break
14114         fi
14115         value=$((value >> 10))
14116         if [ $value -lt 1024 ]; then
14117             size_string=${value}${size[$i]}
14118             break
14119         fi
14120         i=$((i + 1))
14121     done
14122
14123     echo $size_string
14124 }
14125
14126 get_rename_size() {
14127         local size=$1
14128         local context=${2:-.}
14129         local sample=$(do_facet $SINGLEMDS $LCTL \
14130                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14131                 grep -A1 $context |
14132                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14133         echo $sample
14134 }
14135
14136 test_133d() {
14137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14138         remote_ost_nodsh && skip "remote OST with nodsh"
14139         remote_mds_nodsh && skip "remote MDS with nodsh"
14140         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14141                 skip_env "MDS doesn't support rename stats"
14142
14143         local testdir1=$DIR/${tdir}/stats_testdir1
14144         local testdir2=$DIR/${tdir}/stats_testdir2
14145         mkdir -p $DIR/${tdir}
14146
14147         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14148
14149         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14150         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14151
14152         createmany -o $testdir1/test 512 || error "createmany failed"
14153
14154         # check samedir rename size
14155         mv ${testdir1}/test0 ${testdir1}/test_0
14156
14157         local testdir1_size=$(ls -l $DIR/${tdir} |
14158                 awk '/stats_testdir1/ {print $5}')
14159         local testdir2_size=$(ls -l $DIR/${tdir} |
14160                 awk '/stats_testdir2/ {print $5}')
14161
14162         testdir1_size=$(order_2 $testdir1_size)
14163         testdir2_size=$(order_2 $testdir2_size)
14164
14165         testdir1_size=$(size_in_KMGT $testdir1_size)
14166         testdir2_size=$(size_in_KMGT $testdir2_size)
14167
14168         echo "source rename dir size: ${testdir1_size}"
14169         echo "target rename dir size: ${testdir2_size}"
14170
14171         local cmd="do_facet $SINGLEMDS $LCTL "
14172         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14173
14174         eval $cmd || error "$cmd failed"
14175         local samedir=$($cmd | grep 'same_dir')
14176         local same_sample=$(get_rename_size $testdir1_size)
14177         [ -z "$samedir" ] && error "samedir_rename_size count error"
14178         [[ $same_sample -eq 1 ]] ||
14179                 error "samedir_rename_size error $same_sample"
14180         echo "Check same dir rename stats success"
14181
14182         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14183
14184         # check crossdir rename size
14185         mv ${testdir1}/test_0 ${testdir2}/test_0
14186
14187         testdir1_size=$(ls -l $DIR/${tdir} |
14188                 awk '/stats_testdir1/ {print $5}')
14189         testdir2_size=$(ls -l $DIR/${tdir} |
14190                 awk '/stats_testdir2/ {print $5}')
14191
14192         testdir1_size=$(order_2 $testdir1_size)
14193         testdir2_size=$(order_2 $testdir2_size)
14194
14195         testdir1_size=$(size_in_KMGT $testdir1_size)
14196         testdir2_size=$(size_in_KMGT $testdir2_size)
14197
14198         echo "source rename dir size: ${testdir1_size}"
14199         echo "target rename dir size: ${testdir2_size}"
14200
14201         eval $cmd || error "$cmd failed"
14202         local crossdir=$($cmd | grep 'crossdir')
14203         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14204         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14205         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14206         [[ $src_sample -eq 1 ]] ||
14207                 error "crossdir_rename_size error $src_sample"
14208         [[ $tgt_sample -eq 1 ]] ||
14209                 error "crossdir_rename_size error $tgt_sample"
14210         echo "Check cross dir rename stats success"
14211         rm -rf $DIR/${tdir}
14212 }
14213 run_test 133d "Verifying rename_stats ========================================"
14214
14215 test_133e() {
14216         remote_mds_nodsh && skip "remote MDS with nodsh"
14217         remote_ost_nodsh && skip "remote OST with nodsh"
14218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14219
14220         local testdir=$DIR/${tdir}/stats_testdir
14221         local ctr f0 f1 bs=32768 count=42 sum
14222
14223         mkdir -p ${testdir} || error "mkdir failed"
14224
14225         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14226
14227         for ctr in {write,read}_bytes; do
14228                 sync
14229                 cancel_lru_locks osc
14230
14231                 do_facet ost1 $LCTL set_param -n \
14232                         "obdfilter.*.exports.clear=clear"
14233
14234                 if [ $ctr = write_bytes ]; then
14235                         f0=/dev/zero
14236                         f1=${testdir}/${tfile}
14237                 else
14238                         f0=${testdir}/${tfile}
14239                         f1=/dev/null
14240                 fi
14241
14242                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14243                         error "dd failed"
14244                 sync
14245                 cancel_lru_locks osc
14246
14247                 sum=$(do_facet ost1 $LCTL get_param \
14248                         "obdfilter.*.exports.*.stats" |
14249                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14250                                 $1 == ctr { sum += $7 }
14251                                 END { printf("%0.0f", sum) }')
14252
14253                 if ((sum != bs * count)); then
14254                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14255                 fi
14256         done
14257
14258         rm -rf $DIR/${tdir}
14259 }
14260 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14261
14262 test_133f() {
14263         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14264                 skip "too old lustre for get_param -R ($facet_ver)"
14265
14266         # verifying readability.
14267         $LCTL get_param -R '*' &> /dev/null
14268
14269         # Verifing writability with badarea_io.
14270         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14271         local skipped_params='force_lbug|changelog_mask|daemon_file'
14272         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14273                 egrep -v "$skipped_params" |
14274                 xargs -n 1 find $proc_dirs -name |
14275                 xargs -n 1 badarea_io ||
14276                 error "client badarea_io failed"
14277
14278         # remount the FS in case writes/reads /proc break the FS
14279         cleanup || error "failed to unmount"
14280         setup || error "failed to setup"
14281 }
14282 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14283
14284 test_133g() {
14285         remote_mds_nodsh && skip "remote MDS with nodsh"
14286         remote_ost_nodsh && skip "remote OST with nodsh"
14287
14288         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14289         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14290         local facet
14291         for facet in mds1 ost1; do
14292                 local facet_ver=$(lustre_version_code $facet)
14293                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14294                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14295                 else
14296                         log "$facet: too old lustre for get_param -R"
14297                 fi
14298                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14299                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14300                                 tr -d = | egrep -v $skipped_params |
14301                                 xargs -n 1 find $proc_dirs -name |
14302                                 xargs -n 1 badarea_io" ||
14303                                         error "$facet badarea_io failed"
14304                 else
14305                         skip_noexit "$facet: too old lustre for get_param -R"
14306                 fi
14307         done
14308
14309         # remount the FS in case writes/reads /proc break the FS
14310         cleanup || error "failed to unmount"
14311         setup || error "failed to setup"
14312 }
14313 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14314
14315 test_133h() {
14316         remote_mds_nodsh && skip "remote MDS with nodsh"
14317         remote_ost_nodsh && skip "remote OST with nodsh"
14318         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14319                 skip "Need MDS version at least 2.9.54"
14320
14321         local facet
14322         for facet in client mds1 ost1; do
14323                 # Get the list of files that are missing the terminating newline
14324                 local plist=$(do_facet $facet
14325                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14326                 local ent
14327                 for ent in $plist; do
14328                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14329                                 awk -v FS='\v' -v RS='\v\v' \
14330                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14331                                         print FILENAME}'" 2>/dev/null)
14332                         [ -z $missing ] || {
14333                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14334                                 error "file does not end with newline: $facet-$ent"
14335                         }
14336                 done
14337         done
14338 }
14339 run_test 133h "Proc files should end with newlines"
14340
14341 test_134a() {
14342         remote_mds_nodsh && skip "remote MDS with nodsh"
14343         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14344                 skip "Need MDS version at least 2.7.54"
14345
14346         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14347         cancel_lru_locks mdc
14348
14349         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14350         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14351         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14352
14353         local nr=1000
14354         createmany -o $DIR/$tdir/f $nr ||
14355                 error "failed to create $nr files in $DIR/$tdir"
14356         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14357
14358         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14359         do_facet mds1 $LCTL set_param fail_loc=0x327
14360         do_facet mds1 $LCTL set_param fail_val=500
14361         touch $DIR/$tdir/m
14362
14363         echo "sleep 10 seconds ..."
14364         sleep 10
14365         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14366
14367         do_facet mds1 $LCTL set_param fail_loc=0
14368         do_facet mds1 $LCTL set_param fail_val=0
14369         [ $lck_cnt -lt $unused ] ||
14370                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14371
14372         rm $DIR/$tdir/m
14373         unlinkmany $DIR/$tdir/f $nr
14374 }
14375 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14376
14377 test_134b() {
14378         remote_mds_nodsh && skip "remote MDS with nodsh"
14379         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14380                 skip "Need MDS version at least 2.7.54"
14381
14382         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14383         cancel_lru_locks mdc
14384
14385         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14386                         ldlm.lock_reclaim_threshold_mb)
14387         # disable reclaim temporarily
14388         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14389
14390         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14391         do_facet mds1 $LCTL set_param fail_loc=0x328
14392         do_facet mds1 $LCTL set_param fail_val=500
14393
14394         $LCTL set_param debug=+trace
14395
14396         local nr=600
14397         createmany -o $DIR/$tdir/f $nr &
14398         local create_pid=$!
14399
14400         echo "Sleep $TIMEOUT seconds ..."
14401         sleep $TIMEOUT
14402         if ! ps -p $create_pid  > /dev/null 2>&1; then
14403                 do_facet mds1 $LCTL set_param fail_loc=0
14404                 do_facet mds1 $LCTL set_param fail_val=0
14405                 do_facet mds1 $LCTL set_param \
14406                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14407                 error "createmany finished incorrectly!"
14408         fi
14409         do_facet mds1 $LCTL set_param fail_loc=0
14410         do_facet mds1 $LCTL set_param fail_val=0
14411         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14412         wait $create_pid || return 1
14413
14414         unlinkmany $DIR/$tdir/f $nr
14415 }
14416 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14417
14418 test_135() {
14419         remote_mds_nodsh && skip "remote MDS with nodsh"
14420         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14421                 skip "Need MDS version at least 2.13.50"
14422         local fname
14423
14424         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14425
14426 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14427         #set only one record at plain llog
14428         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14429
14430         #fill already existed plain llog each 64767
14431         #wrapping whole catalog
14432         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14433
14434         createmany -o $DIR/$tdir/$tfile_ 64700
14435         for (( i = 0; i < 64700; i = i + 2 ))
14436         do
14437                 rm $DIR/$tdir/$tfile_$i &
14438                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14439                 local pid=$!
14440                 wait $pid
14441         done
14442
14443         #waiting osp synchronization
14444         wait_delete_completed
14445 }
14446 run_test 135 "Race catalog processing"
14447
14448 test_136() {
14449         remote_mds_nodsh && skip "remote MDS with nodsh"
14450         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14451                 skip "Need MDS version at least 2.13.50"
14452         local fname
14453
14454         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14455         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14456         #set only one record at plain llog
14457 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14458         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14459
14460         #fill already existed 2 plain llogs each 64767
14461         #wrapping whole catalog
14462         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14463         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14464         wait_delete_completed
14465
14466         createmany -o $DIR/$tdir/$tfile_ 10
14467         sleep 25
14468
14469         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14470         for (( i = 0; i < 10; i = i + 3 ))
14471         do
14472                 rm $DIR/$tdir/$tfile_$i &
14473                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14474                 local pid=$!
14475                 wait $pid
14476                 sleep 7
14477                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14478         done
14479
14480         #waiting osp synchronization
14481         wait_delete_completed
14482 }
14483 run_test 136 "Race catalog processing 2"
14484
14485 test_140() { #bug-17379
14486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14487
14488         test_mkdir $DIR/$tdir
14489         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14490         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14491
14492         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14493         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14494         local i=0
14495         while i=$((i + 1)); do
14496                 test_mkdir $i
14497                 cd $i || error "Changing to $i"
14498                 ln -s ../stat stat || error "Creating stat symlink"
14499                 # Read the symlink until ELOOP present,
14500                 # not LBUGing the system is considered success,
14501                 # we didn't overrun the stack.
14502                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14503                 if [ $ret -ne 0 ]; then
14504                         if [ $ret -eq 40 ]; then
14505                                 break  # -ELOOP
14506                         else
14507                                 error "Open stat symlink"
14508                                         return
14509                         fi
14510                 fi
14511         done
14512         i=$((i - 1))
14513         echo "The symlink depth = $i"
14514         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14515                 error "Invalid symlink depth"
14516
14517         # Test recursive symlink
14518         ln -s symlink_self symlink_self
14519         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14520         echo "open symlink_self returns $ret"
14521         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14522 }
14523 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14524
14525 test_150a() {
14526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14527
14528         local TF="$TMP/$tfile"
14529
14530         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14531         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14532         cp $TF $DIR/$tfile
14533         cancel_lru_locks $OSC
14534         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14535         remount_client $MOUNT
14536         df -P $MOUNT
14537         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14538
14539         $TRUNCATE $TF 6000
14540         $TRUNCATE $DIR/$tfile 6000
14541         cancel_lru_locks $OSC
14542         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14543
14544         echo "12345" >>$TF
14545         echo "12345" >>$DIR/$tfile
14546         cancel_lru_locks $OSC
14547         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14548
14549         echo "12345" >>$TF
14550         echo "12345" >>$DIR/$tfile
14551         cancel_lru_locks $OSC
14552         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14553 }
14554 run_test 150a "truncate/append tests"
14555
14556 test_150b() {
14557         check_set_fallocate_or_skip
14558
14559         touch $DIR/$tfile
14560         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14561         check_fallocate $DIR/$tfile || error "fallocate failed"
14562 }
14563 run_test 150b "Verify fallocate (prealloc) functionality"
14564
14565 test_150bb() {
14566         check_set_fallocate_or_skip
14567
14568         touch $DIR/$tfile
14569         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14570         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14571         > $DIR/$tfile
14572         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14573         # precomputed md5sum for 20MB of zeroes
14574         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14575         local sum=($(md5sum $DIR/$tfile))
14576
14577         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14578
14579         check_set_fallocate 1
14580
14581         > $DIR/$tfile
14582         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14583         sum=($(md5sum $DIR/$tfile))
14584
14585         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14586 }
14587 run_test 150bb "Verify fallocate modes both zero space"
14588
14589 test_150c() {
14590         check_set_fallocate_or_skip
14591         local striping="-c2"
14592
14593         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14594         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14595         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14596         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14597         local want=$((OSTCOUNT * 1048576))
14598
14599         # Must allocate all requested space, not more than 5% extra
14600         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14601                 error "bytes $bytes is not $want"
14602
14603         rm -f $DIR/$tfile
14604
14605         echo "verify fallocate on PFL file"
14606
14607         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14608
14609         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14610                 error "Create $DIR/$tfile failed"
14611         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14612                         error "fallocate failed"
14613         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14614         want=$((512 * 1048576))
14615
14616         # Must allocate all requested space, not more than 5% extra
14617         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14618                 error "bytes $bytes is not $want"
14619 }
14620 run_test 150c "Verify fallocate Size and Blocks"
14621
14622 test_150d() {
14623         check_set_fallocate_or_skip
14624         local striping="-c2"
14625
14626         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14627
14628         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14629         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14630                 error "setstripe failed"
14631         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14632         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14633         local want=$((OSTCOUNT * 1048576))
14634
14635         # Must allocate all requested space, not more than 5% extra
14636         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14637                 error "bytes $bytes is not $want"
14638 }
14639 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14640
14641 test_150e() {
14642         check_set_fallocate_or_skip
14643
14644         echo "df before:"
14645         $LFS df
14646         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14647         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14648                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14649
14650         # Find OST with Minimum Size
14651         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14652                        sort -un | head -1)
14653
14654         # Get 100MB per OST of the available space to reduce run time
14655         # else 60% of the available space if we are running SLOW tests
14656         if [ $SLOW == "no" ]; then
14657                 local space=$((1024 * 100 * OSTCOUNT))
14658         else
14659                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14660         fi
14661
14662         fallocate -l${space}k $DIR/$tfile ||
14663                 error "fallocate ${space}k $DIR/$tfile failed"
14664         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14665
14666         # get size immediately after fallocate. This should be correctly
14667         # updated
14668         local size=$(stat -c '%s' $DIR/$tfile)
14669         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14670
14671         # Sleep for a while for statfs to get updated. And not pull from cache.
14672         sleep 2
14673
14674         echo "df after fallocate:"
14675         $LFS df
14676
14677         (( size / 1024 == space )) || error "size $size != requested $space"
14678         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14679                 error "used $used < space $space"
14680
14681         rm $DIR/$tfile || error "rm failed"
14682         sync
14683         wait_delete_completed
14684
14685         echo "df after unlink:"
14686         $LFS df
14687 }
14688 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14689
14690 test_150f() {
14691         local size
14692         local blocks
14693         local want_size_before=20480 # in bytes
14694         local want_blocks_before=40 # 512 sized blocks
14695         local want_blocks_after=24  # 512 sized blocks
14696         local length=$(((want_blocks_before - want_blocks_after) * 512))
14697
14698         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14699                 skip "need at least 2.14.0 for fallocate punch"
14700
14701         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14702                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14703         fi
14704
14705         check_set_fallocate_or_skip
14706         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14707
14708         [[ "x$DOM" == "xyes" ]] &&
14709                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14710
14711         echo "Verify fallocate punch: Range within the file range"
14712         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14713                 error "dd failed for bs 4096 and count 5"
14714
14715         # Call fallocate with punch range which is within the file range
14716         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14717                 error "fallocate failed: offset 4096 and length $length"
14718         # client must see changes immediately after fallocate
14719         size=$(stat -c '%s' $DIR/$tfile)
14720         blocks=$(stat -c '%b' $DIR/$tfile)
14721
14722         # Verify punch worked.
14723         (( blocks == want_blocks_after )) ||
14724                 error "punch failed: blocks $blocks != $want_blocks_after"
14725
14726         (( size == want_size_before )) ||
14727                 error "punch failed: size $size != $want_size_before"
14728
14729         # Verify there is hole in file
14730         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14731         # precomputed md5sum
14732         local expect="4a9a834a2db02452929c0a348273b4aa"
14733
14734         cksum=($(md5sum $DIR/$tfile))
14735         [[ "${cksum[0]}" == "$expect" ]] ||
14736                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14737
14738         # Start second sub-case for fallocate punch.
14739         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14740         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14741                 error "dd failed for bs 4096 and count 5"
14742
14743         # Punch range less than block size will have no change in block count
14744         want_blocks_after=40  # 512 sized blocks
14745
14746         # Punch overlaps two blocks and less than blocksize
14747         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14748                 error "fallocate failed: offset 4000 length 3000"
14749         size=$(stat -c '%s' $DIR/$tfile)
14750         blocks=$(stat -c '%b' $DIR/$tfile)
14751
14752         # Verify punch worked.
14753         (( blocks == want_blocks_after )) ||
14754                 error "punch failed: blocks $blocks != $want_blocks_after"
14755
14756         (( size == want_size_before )) ||
14757                 error "punch failed: size $size != $want_size_before"
14758
14759         # Verify if range is really zero'ed out. We expect Zeros.
14760         # precomputed md5sum
14761         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14762         cksum=($(md5sum $DIR/$tfile))
14763         [[ "${cksum[0]}" == "$expect" ]] ||
14764                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14765 }
14766 run_test 150f "Verify fallocate punch functionality"
14767
14768 test_150g() {
14769         local space
14770         local size
14771         local blocks
14772         local blocks_after
14773         local size_after
14774         local BS=4096 # Block size in bytes
14775
14776         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14777                 skip "need at least 2.14.0 for fallocate punch"
14778
14779         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14780                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14781         fi
14782
14783         check_set_fallocate_or_skip
14784         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14785
14786         if [[ "x$DOM" == "xyes" ]]; then
14787                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14788                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14789         else
14790                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14791                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14792         fi
14793
14794         # Get 100MB per OST of the available space to reduce run time
14795         # else 60% of the available space if we are running SLOW tests
14796         if [ $SLOW == "no" ]; then
14797                 space=$((1024 * 100 * OSTCOUNT))
14798         else
14799                 # Find OST with Minimum Size
14800                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14801                         sort -un | head -1)
14802                 echo "min size OST: $space"
14803                 space=$(((space * 60)/100 * OSTCOUNT))
14804         fi
14805         # space in 1k units, round to 4k blocks
14806         local blkcount=$((space * 1024 / $BS))
14807
14808         echo "Verify fallocate punch: Very large Range"
14809         fallocate -l${space}k $DIR/$tfile ||
14810                 error "fallocate ${space}k $DIR/$tfile failed"
14811         # write 1M at the end, start and in the middle
14812         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14813                 error "dd failed: bs $BS count 256"
14814         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14815                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14816         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14817                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14818
14819         # Gather stats.
14820         size=$(stat -c '%s' $DIR/$tfile)
14821
14822         # gather punch length.
14823         local punch_size=$((size - (BS * 2)))
14824
14825         echo "punch_size = $punch_size"
14826         echo "size - punch_size: $((size - punch_size))"
14827         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14828
14829         # Call fallocate to punch all except 2 blocks. We leave the
14830         # first and the last block
14831         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14832         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14833                 error "fallocate failed: offset $BS length $punch_size"
14834
14835         size_after=$(stat -c '%s' $DIR/$tfile)
14836         blocks_after=$(stat -c '%b' $DIR/$tfile)
14837
14838         # Verify punch worked.
14839         # Size should be kept
14840         (( size == size_after )) ||
14841                 error "punch failed: size $size != $size_after"
14842
14843         # two 4k data blocks to remain plus possible 1 extra extent block
14844         (( blocks_after <= ((BS / 512) * 3) )) ||
14845                 error "too many blocks remains: $blocks_after"
14846
14847         # Verify that file has hole between the first and the last blocks
14848         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14849         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14850
14851         echo "Hole at [$hole_start, $hole_end)"
14852         (( hole_start == BS )) ||
14853                 error "no hole at offset $BS after punch"
14854
14855         (( hole_end == BS + punch_size )) ||
14856                 error "data at offset $hole_end < $((BS + punch_size))"
14857 }
14858 run_test 150g "Verify fallocate punch on large range"
14859
14860 #LU-2902 roc_hit was not able to read all values from lproc
14861 function roc_hit_init() {
14862         local list=$(comma_list $(osts_nodes))
14863         local dir=$DIR/$tdir-check
14864         local file=$dir/$tfile
14865         local BEFORE
14866         local AFTER
14867         local idx
14868
14869         test_mkdir $dir
14870         #use setstripe to do a write to every ost
14871         for i in $(seq 0 $((OSTCOUNT-1))); do
14872                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14873                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14874                 idx=$(printf %04x $i)
14875                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14876                         awk '$1 == "cache_access" {sum += $7}
14877                                 END { printf("%0.0f", sum) }')
14878
14879                 cancel_lru_locks osc
14880                 cat $file >/dev/null
14881
14882                 AFTER=$(get_osd_param $list *OST*$idx stats |
14883                         awk '$1 == "cache_access" {sum += $7}
14884                                 END { printf("%0.0f", sum) }')
14885
14886                 echo BEFORE:$BEFORE AFTER:$AFTER
14887                 if ! let "AFTER - BEFORE == 4"; then
14888                         rm -rf $dir
14889                         error "roc_hit is not safe to use"
14890                 fi
14891                 rm $file
14892         done
14893
14894         rm -rf $dir
14895 }
14896
14897 function roc_hit() {
14898         local list=$(comma_list $(osts_nodes))
14899         echo $(get_osd_param $list '' stats |
14900                 awk '$1 == "cache_hit" {sum += $7}
14901                         END { printf("%0.0f", sum) }')
14902 }
14903
14904 function set_cache() {
14905         local on=1
14906
14907         if [ "$2" == "off" ]; then
14908                 on=0;
14909         fi
14910         local list=$(comma_list $(osts_nodes))
14911         set_osd_param $list '' $1_cache_enable $on
14912
14913         cancel_lru_locks osc
14914 }
14915
14916 test_151() {
14917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14918         remote_ost_nodsh && skip "remote OST with nodsh"
14919
14920         local CPAGES=3
14921         local list=$(comma_list $(osts_nodes))
14922
14923         # check whether obdfilter is cache capable at all
14924         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14925                 skip "not cache-capable obdfilter"
14926         fi
14927
14928         # check cache is enabled on all obdfilters
14929         if get_osd_param $list '' read_cache_enable | grep 0; then
14930                 skip "oss cache is disabled"
14931         fi
14932
14933         set_osd_param $list '' writethrough_cache_enable 1
14934
14935         # check write cache is enabled on all obdfilters
14936         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14937                 skip "oss write cache is NOT enabled"
14938         fi
14939
14940         roc_hit_init
14941
14942         #define OBD_FAIL_OBD_NO_LRU  0x609
14943         do_nodes $list $LCTL set_param fail_loc=0x609
14944
14945         # pages should be in the case right after write
14946         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14947                 error "dd failed"
14948
14949         local BEFORE=$(roc_hit)
14950         cancel_lru_locks osc
14951         cat $DIR/$tfile >/dev/null
14952         local AFTER=$(roc_hit)
14953
14954         do_nodes $list $LCTL set_param fail_loc=0
14955
14956         if ! let "AFTER - BEFORE == CPAGES"; then
14957                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14958         fi
14959
14960         cancel_lru_locks osc
14961         # invalidates OST cache
14962         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14963         set_osd_param $list '' read_cache_enable 0
14964         cat $DIR/$tfile >/dev/null
14965
14966         # now data shouldn't be found in the cache
14967         BEFORE=$(roc_hit)
14968         cancel_lru_locks osc
14969         cat $DIR/$tfile >/dev/null
14970         AFTER=$(roc_hit)
14971         if let "AFTER - BEFORE != 0"; then
14972                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14973         fi
14974
14975         set_osd_param $list '' read_cache_enable 1
14976         rm -f $DIR/$tfile
14977 }
14978 run_test 151 "test cache on oss and controls ==============================="
14979
14980 test_152() {
14981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14982
14983         local TF="$TMP/$tfile"
14984
14985         # simulate ENOMEM during write
14986 #define OBD_FAIL_OST_NOMEM      0x226
14987         lctl set_param fail_loc=0x80000226
14988         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14989         cp $TF $DIR/$tfile
14990         sync || error "sync failed"
14991         lctl set_param fail_loc=0
14992
14993         # discard client's cache
14994         cancel_lru_locks osc
14995
14996         # simulate ENOMEM during read
14997         lctl set_param fail_loc=0x80000226
14998         cmp $TF $DIR/$tfile || error "cmp failed"
14999         lctl set_param fail_loc=0
15000
15001         rm -f $TF
15002 }
15003 run_test 152 "test read/write with enomem ============================"
15004
15005 test_153() {
15006         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15007 }
15008 run_test 153 "test if fdatasync does not crash ======================="
15009
15010 dot_lustre_fid_permission_check() {
15011         local fid=$1
15012         local ffid=$MOUNT/.lustre/fid/$fid
15013         local test_dir=$2
15014
15015         echo "stat fid $fid"
15016         stat $ffid > /dev/null || error "stat $ffid failed."
15017         echo "touch fid $fid"
15018         touch $ffid || error "touch $ffid failed."
15019         echo "write to fid $fid"
15020         cat /etc/hosts > $ffid || error "write $ffid failed."
15021         echo "read fid $fid"
15022         diff /etc/hosts $ffid || error "read $ffid failed."
15023         echo "append write to fid $fid"
15024         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15025         echo "rename fid $fid"
15026         mv $ffid $test_dir/$tfile.1 &&
15027                 error "rename $ffid to $tfile.1 should fail."
15028         touch $test_dir/$tfile.1
15029         mv $test_dir/$tfile.1 $ffid &&
15030                 error "rename $tfile.1 to $ffid should fail."
15031         rm -f $test_dir/$tfile.1
15032         echo "truncate fid $fid"
15033         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15034         echo "link fid $fid"
15035         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15036         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15037                 echo "setfacl fid $fid"
15038                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15039                 echo "getfacl fid $fid"
15040                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15041         fi
15042         echo "unlink fid $fid"
15043         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15044         echo "mknod fid $fid"
15045         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15046
15047         fid=[0xf00000400:0x1:0x0]
15048         ffid=$MOUNT/.lustre/fid/$fid
15049
15050         echo "stat non-exist fid $fid"
15051         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15052         echo "write to non-exist fid $fid"
15053         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15054         echo "link new fid $fid"
15055         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15056
15057         mkdir -p $test_dir/$tdir
15058         touch $test_dir/$tdir/$tfile
15059         fid=$($LFS path2fid $test_dir/$tdir)
15060         rc=$?
15061         [ $rc -ne 0 ] &&
15062                 error "error: could not get fid for $test_dir/$dir/$tfile."
15063
15064         ffid=$MOUNT/.lustre/fid/$fid
15065
15066         echo "ls $fid"
15067         ls $ffid > /dev/null || error "ls $ffid failed."
15068         echo "touch $fid/$tfile.1"
15069         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15070
15071         echo "touch $MOUNT/.lustre/fid/$tfile"
15072         touch $MOUNT/.lustre/fid/$tfile && \
15073                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15074
15075         echo "setxattr to $MOUNT/.lustre/fid"
15076         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15077
15078         echo "listxattr for $MOUNT/.lustre/fid"
15079         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15080
15081         echo "delxattr from $MOUNT/.lustre/fid"
15082         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15083
15084         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15085         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15086                 error "touch invalid fid should fail."
15087
15088         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15089         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15090                 error "touch non-normal fid should fail."
15091
15092         echo "rename $tdir to $MOUNT/.lustre/fid"
15093         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15094                 error "rename to $MOUNT/.lustre/fid should fail."
15095
15096         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15097         then            # LU-3547
15098                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15099                 local new_obf_mode=777
15100
15101                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15102                 chmod $new_obf_mode $DIR/.lustre/fid ||
15103                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15104
15105                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15106                 [ $obf_mode -eq $new_obf_mode ] ||
15107                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15108
15109                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15110                 chmod $old_obf_mode $DIR/.lustre/fid ||
15111                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15112         fi
15113
15114         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15115         fid=$($LFS path2fid $test_dir/$tfile-2)
15116
15117         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15118         then # LU-5424
15119                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15120                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15121                         error "create lov data thru .lustre failed"
15122         fi
15123         echo "cp /etc/passwd $test_dir/$tfile-2"
15124         cp /etc/passwd $test_dir/$tfile-2 ||
15125                 error "copy to $test_dir/$tfile-2 failed."
15126         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15127         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15128                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15129
15130         rm -rf $test_dir/tfile.lnk
15131         rm -rf $test_dir/$tfile-2
15132 }
15133
15134 test_154A() {
15135         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15136                 skip "Need MDS version at least 2.4.1"
15137
15138         local tf=$DIR/$tfile
15139         touch $tf
15140
15141         local fid=$($LFS path2fid $tf)
15142         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15143
15144         # check that we get the same pathname back
15145         local rootpath
15146         local found
15147         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15148                 echo "$rootpath $fid"
15149                 found=$($LFS fid2path $rootpath "$fid")
15150                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15151                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15152         done
15153
15154         # check wrong root path format
15155         rootpath=$MOUNT"_wrong"
15156         found=$($LFS fid2path $rootpath "$fid")
15157         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15158 }
15159 run_test 154A "lfs path2fid and fid2path basic checks"
15160
15161 test_154B() {
15162         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15163                 skip "Need MDS version at least 2.4.1"
15164
15165         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15166         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15167         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15168         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15169
15170         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15171         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15172
15173         # check that we get the same pathname
15174         echo "PFID: $PFID, name: $name"
15175         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15176         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15177         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15178                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15179
15180         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15181 }
15182 run_test 154B "verify the ll_decode_linkea tool"
15183
15184 test_154a() {
15185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15186         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15187         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15188                 skip "Need MDS version at least 2.2.51"
15189         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15190
15191         cp /etc/hosts $DIR/$tfile
15192
15193         fid=$($LFS path2fid $DIR/$tfile)
15194         rc=$?
15195         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15196
15197         dot_lustre_fid_permission_check "$fid" $DIR ||
15198                 error "dot lustre permission check $fid failed"
15199
15200         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15201
15202         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15203
15204         touch $MOUNT/.lustre/file &&
15205                 error "creation is not allowed under .lustre"
15206
15207         mkdir $MOUNT/.lustre/dir &&
15208                 error "mkdir is not allowed under .lustre"
15209
15210         rm -rf $DIR/$tfile
15211 }
15212 run_test 154a "Open-by-FID"
15213
15214 test_154b() {
15215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15216         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15217         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15218         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15219                 skip "Need MDS version at least 2.2.51"
15220
15221         local remote_dir=$DIR/$tdir/remote_dir
15222         local MDTIDX=1
15223         local rc=0
15224
15225         mkdir -p $DIR/$tdir
15226         $LFS mkdir -i $MDTIDX $remote_dir ||
15227                 error "create remote directory failed"
15228
15229         cp /etc/hosts $remote_dir/$tfile
15230
15231         fid=$($LFS path2fid $remote_dir/$tfile)
15232         rc=$?
15233         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15234
15235         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15236                 error "dot lustre permission check $fid failed"
15237         rm -rf $DIR/$tdir
15238 }
15239 run_test 154b "Open-by-FID for remote directory"
15240
15241 test_154c() {
15242         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15243                 skip "Need MDS version at least 2.4.1"
15244
15245         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15246         local FID1=$($LFS path2fid $DIR/$tfile.1)
15247         local FID2=$($LFS path2fid $DIR/$tfile.2)
15248         local FID3=$($LFS path2fid $DIR/$tfile.3)
15249
15250         local N=1
15251         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15252                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15253                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15254                 local want=FID$N
15255                 [ "$FID" = "${!want}" ] ||
15256                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15257                 N=$((N + 1))
15258         done
15259
15260         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15261         do
15262                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15263                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15264                 N=$((N + 1))
15265         done
15266 }
15267 run_test 154c "lfs path2fid and fid2path multiple arguments"
15268
15269 test_154d() {
15270         remote_mds_nodsh && skip "remote MDS with nodsh"
15271         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15272                 skip "Need MDS version at least 2.5.53"
15273
15274         if remote_mds; then
15275                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15276         else
15277                 nid="0@lo"
15278         fi
15279         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15280         local fd
15281         local cmd
15282
15283         rm -f $DIR/$tfile
15284         touch $DIR/$tfile
15285
15286         local fid=$($LFS path2fid $DIR/$tfile)
15287         # Open the file
15288         fd=$(free_fd)
15289         cmd="exec $fd<$DIR/$tfile"
15290         eval $cmd
15291         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15292         echo "$fid_list" | grep "$fid"
15293         rc=$?
15294
15295         cmd="exec $fd>/dev/null"
15296         eval $cmd
15297         if [ $rc -ne 0 ]; then
15298                 error "FID $fid not found in open files list $fid_list"
15299         fi
15300 }
15301 run_test 154d "Verify open file fid"
15302
15303 test_154e()
15304 {
15305         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15306                 skip "Need MDS version at least 2.6.50"
15307
15308         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15309                 error ".lustre returned by readdir"
15310         fi
15311 }
15312 run_test 154e ".lustre is not returned by readdir"
15313
15314 test_154f() {
15315         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15316
15317         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15318         mkdir_on_mdt0 $DIR/$tdir
15319         # test dirs inherit from its stripe
15320         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15321         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15322         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15323         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15324         touch $DIR/f
15325
15326         # get fid of parents
15327         local FID0=$($LFS path2fid $DIR/$tdir)
15328         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15329         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15330         local FID3=$($LFS path2fid $DIR)
15331
15332         # check that path2fid --parents returns expected <parent_fid>/name
15333         # 1) test for a directory (single parent)
15334         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15335         [ "$parent" == "$FID0/foo1" ] ||
15336                 error "expected parent: $FID0/foo1, got: $parent"
15337
15338         # 2) test for a file with nlink > 1 (multiple parents)
15339         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15340         echo "$parent" | grep -F "$FID1/$tfile" ||
15341                 error "$FID1/$tfile not returned in parent list"
15342         echo "$parent" | grep -F "$FID2/link" ||
15343                 error "$FID2/link not returned in parent list"
15344
15345         # 3) get parent by fid
15346         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15347         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15348         echo "$parent" | grep -F "$FID1/$tfile" ||
15349                 error "$FID1/$tfile not returned in parent list (by fid)"
15350         echo "$parent" | grep -F "$FID2/link" ||
15351                 error "$FID2/link not returned in parent list (by fid)"
15352
15353         # 4) test for entry in root directory
15354         parent=$($LFS path2fid --parents $DIR/f)
15355         echo "$parent" | grep -F "$FID3/f" ||
15356                 error "$FID3/f not returned in parent list"
15357
15358         # 5) test it on root directory
15359         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15360                 error "$MOUNT should not have parents"
15361
15362         # enable xattr caching and check that linkea is correctly updated
15363         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15364         save_lustre_params client "llite.*.xattr_cache" > $save
15365         lctl set_param llite.*.xattr_cache 1
15366
15367         # 6.1) linkea update on rename
15368         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15369
15370         # get parents by fid
15371         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15372         # foo1 should no longer be returned in parent list
15373         echo "$parent" | grep -F "$FID1" &&
15374                 error "$FID1 should no longer be in parent list"
15375         # the new path should appear
15376         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15377                 error "$FID2/$tfile.moved is not in parent list"
15378
15379         # 6.2) linkea update on unlink
15380         rm -f $DIR/$tdir/foo2/link
15381         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15382         # foo2/link should no longer be returned in parent list
15383         echo "$parent" | grep -F "$FID2/link" &&
15384                 error "$FID2/link should no longer be in parent list"
15385         true
15386
15387         rm -f $DIR/f
15388         restore_lustre_params < $save
15389         rm -f $save
15390 }
15391 run_test 154f "get parent fids by reading link ea"
15392
15393 test_154g()
15394 {
15395         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15396         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15397            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15398                 skip "Need MDS version at least 2.6.92"
15399
15400         mkdir_on_mdt0 $DIR/$tdir
15401         llapi_fid_test -d $DIR/$tdir
15402 }
15403 run_test 154g "various llapi FID tests"
15404
15405 test_155_small_load() {
15406     local temp=$TMP/$tfile
15407     local file=$DIR/$tfile
15408
15409     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15410         error "dd of=$temp bs=6096 count=1 failed"
15411     cp $temp $file
15412     cancel_lru_locks $OSC
15413     cmp $temp $file || error "$temp $file differ"
15414
15415     $TRUNCATE $temp 6000
15416     $TRUNCATE $file 6000
15417     cmp $temp $file || error "$temp $file differ (truncate1)"
15418
15419     echo "12345" >>$temp
15420     echo "12345" >>$file
15421     cmp $temp $file || error "$temp $file differ (append1)"
15422
15423     echo "12345" >>$temp
15424     echo "12345" >>$file
15425     cmp $temp $file || error "$temp $file differ (append2)"
15426
15427     rm -f $temp $file
15428     true
15429 }
15430
15431 test_155_big_load() {
15432         remote_ost_nodsh && skip "remote OST with nodsh"
15433
15434         local temp=$TMP/$tfile
15435         local file=$DIR/$tfile
15436
15437         free_min_max
15438         local cache_size=$(do_facet ost$((MAXI+1)) \
15439                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15440         local large_file_size=$((cache_size * 2))
15441
15442         echo "OSS cache size: $cache_size KB"
15443         echo "Large file size: $large_file_size KB"
15444
15445         [ $MAXV -le $large_file_size ] &&
15446                 skip_env "max available OST size needs > $large_file_size KB"
15447
15448         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15449
15450         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15451                 error "dd of=$temp bs=$large_file_size count=1k failed"
15452         cp $temp $file
15453         ls -lh $temp $file
15454         cancel_lru_locks osc
15455         cmp $temp $file || error "$temp $file differ"
15456
15457         rm -f $temp $file
15458         true
15459 }
15460
15461 save_writethrough() {
15462         local facets=$(get_facets OST)
15463
15464         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15465 }
15466
15467 test_155a() {
15468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15469
15470         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15471
15472         save_writethrough $p
15473
15474         set_cache read on
15475         set_cache writethrough on
15476         test_155_small_load
15477         restore_lustre_params < $p
15478         rm -f $p
15479 }
15480 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15481
15482 test_155b() {
15483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15484
15485         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15486
15487         save_writethrough $p
15488
15489         set_cache read on
15490         set_cache writethrough off
15491         test_155_small_load
15492         restore_lustre_params < $p
15493         rm -f $p
15494 }
15495 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15496
15497 test_155c() {
15498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15499
15500         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15501
15502         save_writethrough $p
15503
15504         set_cache read off
15505         set_cache writethrough on
15506         test_155_small_load
15507         restore_lustre_params < $p
15508         rm -f $p
15509 }
15510 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15511
15512 test_155d() {
15513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15514
15515         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15516
15517         save_writethrough $p
15518
15519         set_cache read off
15520         set_cache writethrough off
15521         test_155_small_load
15522         restore_lustre_params < $p
15523         rm -f $p
15524 }
15525 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15526
15527 test_155e() {
15528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15529
15530         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15531
15532         save_writethrough $p
15533
15534         set_cache read on
15535         set_cache writethrough on
15536         test_155_big_load
15537         restore_lustre_params < $p
15538         rm -f $p
15539 }
15540 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15541
15542 test_155f() {
15543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15544
15545         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15546
15547         save_writethrough $p
15548
15549         set_cache read on
15550         set_cache writethrough off
15551         test_155_big_load
15552         restore_lustre_params < $p
15553         rm -f $p
15554 }
15555 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15556
15557 test_155g() {
15558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15559
15560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15561
15562         save_writethrough $p
15563
15564         set_cache read off
15565         set_cache writethrough on
15566         test_155_big_load
15567         restore_lustre_params < $p
15568         rm -f $p
15569 }
15570 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15571
15572 test_155h() {
15573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15574
15575         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15576
15577         save_writethrough $p
15578
15579         set_cache read off
15580         set_cache writethrough off
15581         test_155_big_load
15582         restore_lustre_params < $p
15583         rm -f $p
15584 }
15585 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15586
15587 test_156() {
15588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15589         remote_ost_nodsh && skip "remote OST with nodsh"
15590         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15591                 skip "stats not implemented on old servers"
15592         [ "$ost1_FSTYPE" = "zfs" ] &&
15593                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15594
15595         local CPAGES=3
15596         local BEFORE
15597         local AFTER
15598         local file="$DIR/$tfile"
15599         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15600
15601         save_writethrough $p
15602         roc_hit_init
15603
15604         log "Turn on read and write cache"
15605         set_cache read on
15606         set_cache writethrough on
15607
15608         log "Write data and read it back."
15609         log "Read should be satisfied from the cache."
15610         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15611         BEFORE=$(roc_hit)
15612         cancel_lru_locks osc
15613         cat $file >/dev/null
15614         AFTER=$(roc_hit)
15615         if ! let "AFTER - BEFORE == CPAGES"; then
15616                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15617         else
15618                 log "cache hits: before: $BEFORE, after: $AFTER"
15619         fi
15620
15621         log "Read again; it should be satisfied from the cache."
15622         BEFORE=$AFTER
15623         cancel_lru_locks osc
15624         cat $file >/dev/null
15625         AFTER=$(roc_hit)
15626         if ! let "AFTER - BEFORE == CPAGES"; then
15627                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15628         else
15629                 log "cache hits:: before: $BEFORE, after: $AFTER"
15630         fi
15631
15632         log "Turn off the read cache and turn on the write cache"
15633         set_cache read off
15634         set_cache writethrough on
15635
15636         log "Read again; it should be satisfied from the cache."
15637         BEFORE=$(roc_hit)
15638         cancel_lru_locks osc
15639         cat $file >/dev/null
15640         AFTER=$(roc_hit)
15641         if ! let "AFTER - BEFORE == CPAGES"; then
15642                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15643         else
15644                 log "cache hits:: before: $BEFORE, after: $AFTER"
15645         fi
15646
15647         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15648                 # > 2.12.56 uses pagecache if cached
15649                 log "Read again; it should not be satisfied from the cache."
15650                 BEFORE=$AFTER
15651                 cancel_lru_locks osc
15652                 cat $file >/dev/null
15653                 AFTER=$(roc_hit)
15654                 if ! let "AFTER - BEFORE == 0"; then
15655                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15656                 else
15657                         log "cache hits:: before: $BEFORE, after: $AFTER"
15658                 fi
15659         fi
15660
15661         log "Write data and read it back."
15662         log "Read should be satisfied from the cache."
15663         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15664         BEFORE=$(roc_hit)
15665         cancel_lru_locks osc
15666         cat $file >/dev/null
15667         AFTER=$(roc_hit)
15668         if ! let "AFTER - BEFORE == CPAGES"; then
15669                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15670         else
15671                 log "cache hits:: before: $BEFORE, after: $AFTER"
15672         fi
15673
15674         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15675                 # > 2.12.56 uses pagecache if cached
15676                 log "Read again; it should not be satisfied from the cache."
15677                 BEFORE=$AFTER
15678                 cancel_lru_locks osc
15679                 cat $file >/dev/null
15680                 AFTER=$(roc_hit)
15681                 if ! let "AFTER - BEFORE == 0"; then
15682                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15683                 else
15684                         log "cache hits:: before: $BEFORE, after: $AFTER"
15685                 fi
15686         fi
15687
15688         log "Turn off read and write cache"
15689         set_cache read off
15690         set_cache writethrough off
15691
15692         log "Write data and read it back"
15693         log "It should not be satisfied from the cache."
15694         rm -f $file
15695         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15696         cancel_lru_locks osc
15697         BEFORE=$(roc_hit)
15698         cat $file >/dev/null
15699         AFTER=$(roc_hit)
15700         if ! let "AFTER - BEFORE == 0"; then
15701                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15702         else
15703                 log "cache hits:: before: $BEFORE, after: $AFTER"
15704         fi
15705
15706         log "Turn on the read cache and turn off the write cache"
15707         set_cache read on
15708         set_cache writethrough off
15709
15710         log "Write data and read it back"
15711         log "It should not be satisfied from the cache."
15712         rm -f $file
15713         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15714         BEFORE=$(roc_hit)
15715         cancel_lru_locks osc
15716         cat $file >/dev/null
15717         AFTER=$(roc_hit)
15718         if ! let "AFTER - BEFORE == 0"; then
15719                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15720         else
15721                 log "cache hits:: before: $BEFORE, after: $AFTER"
15722         fi
15723
15724         log "Read again; it should be satisfied from the cache."
15725         BEFORE=$(roc_hit)
15726         cancel_lru_locks osc
15727         cat $file >/dev/null
15728         AFTER=$(roc_hit)
15729         if ! let "AFTER - BEFORE == CPAGES"; then
15730                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15731         else
15732                 log "cache hits:: before: $BEFORE, after: $AFTER"
15733         fi
15734
15735         restore_lustre_params < $p
15736         rm -f $p $file
15737 }
15738 run_test 156 "Verification of tunables"
15739
15740 test_160a() {
15741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15742         remote_mds_nodsh && skip "remote MDS with nodsh"
15743         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15744                 skip "Need MDS version at least 2.2.0"
15745
15746         changelog_register || error "changelog_register failed"
15747         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15748         changelog_users $SINGLEMDS | grep -q $cl_user ||
15749                 error "User $cl_user not found in changelog_users"
15750
15751         mkdir_on_mdt0 $DIR/$tdir
15752
15753         # change something
15754         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15755         changelog_clear 0 || error "changelog_clear failed"
15756         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15757         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15758         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15759         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15760         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15761         rm $DIR/$tdir/pics/desktop.jpg
15762
15763         echo "verifying changelog mask"
15764         changelog_chmask "-MKDIR"
15765         changelog_chmask "-CLOSE"
15766
15767         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15768         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15769
15770         changelog_chmask "+MKDIR"
15771         changelog_chmask "+CLOSE"
15772
15773         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15774         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15775
15776         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15777         CLOSES=$(changelog_dump | grep -c "CLOSE")
15778         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15779         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15780
15781         # verify contents
15782         echo "verifying target fid"
15783         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15784         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15785         [ "$fidc" == "$fidf" ] ||
15786                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15787         echo "verifying parent fid"
15788         # The FID returned from the Changelog may be the directory shard on
15789         # a different MDT, and not the FID returned by path2fid on the parent.
15790         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15791         # since this is what will matter when recreating this file in the tree.
15792         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15793         local pathp=$($LFS fid2path $MOUNT "$fidp")
15794         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15795                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15796
15797         echo "getting records for $cl_user"
15798         changelog_users $SINGLEMDS
15799         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15800         local nclr=3
15801         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15802                 error "changelog_clear failed"
15803         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15804         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15805         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15806                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15807
15808         local min0_rec=$(changelog_users $SINGLEMDS |
15809                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15810         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15811                           awk '{ print $1; exit; }')
15812
15813         changelog_dump | tail -n 5
15814         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15815         [ $first_rec == $((min0_rec + 1)) ] ||
15816                 error "first index should be $min0_rec + 1 not $first_rec"
15817
15818         # LU-3446 changelog index reset on MDT restart
15819         local cur_rec1=$(changelog_users $SINGLEMDS |
15820                          awk '/^current.index:/ { print $NF }')
15821         changelog_clear 0 ||
15822                 error "clear all changelog records for $cl_user failed"
15823         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15824         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15825                 error "Fail to start $SINGLEMDS"
15826         local cur_rec2=$(changelog_users $SINGLEMDS |
15827                          awk '/^current.index:/ { print $NF }')
15828         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15829         [ $cur_rec1 == $cur_rec2 ] ||
15830                 error "current index should be $cur_rec1 not $cur_rec2"
15831
15832         echo "verifying users from this test are deregistered"
15833         changelog_deregister || error "changelog_deregister failed"
15834         changelog_users $SINGLEMDS | grep -q $cl_user &&
15835                 error "User '$cl_user' still in changelog_users"
15836
15837         # lctl get_param -n mdd.*.changelog_users
15838         # current_index: 144
15839         # ID    index (idle seconds)
15840         # cl3   144   (2) mask=<list>
15841         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15842                 # this is the normal case where all users were deregistered
15843                 # make sure no new records are added when no users are present
15844                 local last_rec1=$(changelog_users $SINGLEMDS |
15845                                   awk '/^current.index:/ { print $NF }')
15846                 touch $DIR/$tdir/chloe
15847                 local last_rec2=$(changelog_users $SINGLEMDS |
15848                                   awk '/^current.index:/ { print $NF }')
15849                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15850                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15851         else
15852                 # any changelog users must be leftovers from a previous test
15853                 changelog_users $SINGLEMDS
15854                 echo "other changelog users; can't verify off"
15855         fi
15856 }
15857 run_test 160a "changelog sanity"
15858
15859 test_160b() { # LU-3587
15860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15861         remote_mds_nodsh && skip "remote MDS with nodsh"
15862         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15863                 skip "Need MDS version at least 2.2.0"
15864
15865         changelog_register || error "changelog_register failed"
15866         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15867         changelog_users $SINGLEMDS | grep -q $cl_user ||
15868                 error "User '$cl_user' not found in changelog_users"
15869
15870         local longname1=$(str_repeat a 255)
15871         local longname2=$(str_repeat b 255)
15872
15873         cd $DIR
15874         echo "creating very long named file"
15875         touch $longname1 || error "create of '$longname1' failed"
15876         echo "renaming very long named file"
15877         mv $longname1 $longname2
15878
15879         changelog_dump | grep RENME | tail -n 5
15880         rm -f $longname2
15881 }
15882 run_test 160b "Verify that very long rename doesn't crash in changelog"
15883
15884 test_160c() {
15885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15886         remote_mds_nodsh && skip "remote MDS with nodsh"
15887
15888         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15889                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15890                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15891                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15892
15893         local rc=0
15894
15895         # Registration step
15896         changelog_register || error "changelog_register failed"
15897
15898         rm -rf $DIR/$tdir
15899         mkdir -p $DIR/$tdir
15900         $MCREATE $DIR/$tdir/foo_160c
15901         changelog_chmask "-TRUNC"
15902         $TRUNCATE $DIR/$tdir/foo_160c 200
15903         changelog_chmask "+TRUNC"
15904         $TRUNCATE $DIR/$tdir/foo_160c 199
15905         changelog_dump | tail -n 5
15906         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15907         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15908 }
15909 run_test 160c "verify that changelog log catch the truncate event"
15910
15911 test_160d() {
15912         remote_mds_nodsh && skip "remote MDS with nodsh"
15913         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15915         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15916                 skip "Need MDS version at least 2.7.60"
15917
15918         # Registration step
15919         changelog_register || error "changelog_register failed"
15920
15921         mkdir -p $DIR/$tdir/migrate_dir
15922         changelog_clear 0 || error "changelog_clear failed"
15923
15924         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15925         changelog_dump | tail -n 5
15926         local migrates=$(changelog_dump | grep -c "MIGRT")
15927         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15928 }
15929 run_test 160d "verify that changelog log catch the migrate event"
15930
15931 test_160e() {
15932         remote_mds_nodsh && skip "remote MDS with nodsh"
15933
15934         # Create a user
15935         changelog_register || error "changelog_register failed"
15936
15937         local MDT0=$(facet_svc $SINGLEMDS)
15938         local rc
15939
15940         # No user (expect fail)
15941         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15942         rc=$?
15943         if [ $rc -eq 0 ]; then
15944                 error "Should fail without user"
15945         elif [ $rc -ne 4 ]; then
15946                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15947         fi
15948
15949         # Delete a future user (expect fail)
15950         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15951         rc=$?
15952         if [ $rc -eq 0 ]; then
15953                 error "Deleted non-existant user cl77"
15954         elif [ $rc -ne 2 ]; then
15955                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15956         fi
15957
15958         # Clear to a bad index (1 billion should be safe)
15959         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15960         rc=$?
15961
15962         if [ $rc -eq 0 ]; then
15963                 error "Successfully cleared to invalid CL index"
15964         elif [ $rc -ne 22 ]; then
15965                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15966         fi
15967 }
15968 run_test 160e "changelog negative testing (should return errors)"
15969
15970 test_160f() {
15971         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15972         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15973                 skip "Need MDS version at least 2.10.56"
15974
15975         local mdts=$(comma_list $(mdts_nodes))
15976
15977         # Create a user
15978         changelog_register || error "first changelog_register failed"
15979         changelog_register || error "second changelog_register failed"
15980         local cl_users
15981         declare -A cl_user1
15982         declare -A cl_user2
15983         local user_rec1
15984         local user_rec2
15985         local i
15986
15987         # generate some changelog records to accumulate on each MDT
15988         # use all_char because created files should be evenly distributed
15989         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15990                 error "test_mkdir $tdir failed"
15991         log "$(date +%s): creating first files"
15992         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15993                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15994                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15995         done
15996
15997         # check changelogs have been generated
15998         local start=$SECONDS
15999         local idle_time=$((MDSCOUNT * 5 + 5))
16000         local nbcl=$(changelog_dump | wc -l)
16001         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16002
16003         for param in "changelog_max_idle_time=$idle_time" \
16004                      "changelog_gc=1" \
16005                      "changelog_min_gc_interval=2" \
16006                      "changelog_min_free_cat_entries=3"; do
16007                 local MDT0=$(facet_svc $SINGLEMDS)
16008                 local var="${param%=*}"
16009                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16010
16011                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16012                 do_nodes $mdts $LCTL set_param mdd.*.$param
16013         done
16014
16015         # force cl_user2 to be idle (1st part), but also cancel the
16016         # cl_user1 records so that it is not evicted later in the test.
16017         local sleep1=$((idle_time / 2))
16018         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16019         sleep $sleep1
16020
16021         # simulate changelog catalog almost full
16022         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16023         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16024
16025         for i in $(seq $MDSCOUNT); do
16026                 cl_users=(${CL_USERS[mds$i]})
16027                 cl_user1[mds$i]="${cl_users[0]}"
16028                 cl_user2[mds$i]="${cl_users[1]}"
16029
16030                 [ -n "${cl_user1[mds$i]}" ] ||
16031                         error "mds$i: no user registered"
16032                 [ -n "${cl_user2[mds$i]}" ] ||
16033                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16034
16035                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16036                 [ -n "$user_rec1" ] ||
16037                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16038                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16039                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16040                 [ -n "$user_rec2" ] ||
16041                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16042                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16043                      "$user_rec1 + 2 == $user_rec2"
16044                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16045                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16046                               "$user_rec1 + 2, but is $user_rec2"
16047                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16048                 [ -n "$user_rec2" ] ||
16049                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16050                 [ $user_rec1 == $user_rec2 ] ||
16051                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16052                               "$user_rec1, but is $user_rec2"
16053         done
16054
16055         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16056         local sleep2=$((idle_time - (SECONDS - start) + 1))
16057         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16058         sleep $sleep2
16059
16060         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16061         # cl_user1 should be OK because it recently processed records.
16062         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16063         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16064                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16065                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16066         done
16067
16068         # ensure gc thread is done
16069         for i in $(mdts_nodes); do
16070                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16071                         error "$i: GC-thread not done"
16072         done
16073
16074         local first_rec
16075         for (( i = 1; i <= MDSCOUNT; i++ )); do
16076                 # check cl_user1 still registered
16077                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16078                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16079                 # check cl_user2 unregistered
16080                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16081                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16082
16083                 # check changelogs are present and starting at $user_rec1 + 1
16084                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16085                 [ -n "$user_rec1" ] ||
16086                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16087                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16088                             awk '{ print $1; exit; }')
16089
16090                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16091                 [ $((user_rec1 + 1)) == $first_rec ] ||
16092                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16093         done
16094 }
16095 run_test 160f "changelog garbage collect (timestamped users)"
16096
16097 test_160g() {
16098         remote_mds_nodsh && skip "remote MDS with nodsh"
16099         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16100                 skip "Need MDS version at least 2.14.55"
16101
16102         local mdts=$(comma_list $(mdts_nodes))
16103
16104         # Create a user
16105         changelog_register || error "first changelog_register failed"
16106         changelog_register || error "second changelog_register failed"
16107         local cl_users
16108         declare -A cl_user1
16109         declare -A cl_user2
16110         local user_rec1
16111         local user_rec2
16112         local i
16113
16114         # generate some changelog records to accumulate on each MDT
16115         # use all_char because created files should be evenly distributed
16116         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16117                 error "test_mkdir $tdir failed"
16118         for ((i = 0; i < MDSCOUNT; i++)); do
16119                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16120                         error "create $DIR/$tdir/d$i.1 failed"
16121         done
16122
16123         # check changelogs have been generated
16124         local nbcl=$(changelog_dump | wc -l)
16125         (( $nbcl > 0 )) || error "no changelogs found"
16126
16127         # reduce the max_idle_indexes value to make sure we exceed it
16128         for param in "changelog_max_idle_indexes=2" \
16129                      "changelog_gc=1" \
16130                      "changelog_min_gc_interval=2"; do
16131                 local MDT0=$(facet_svc $SINGLEMDS)
16132                 local var="${param%=*}"
16133                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16134
16135                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16136                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16137                         error "unable to set mdd.*.$param"
16138         done
16139
16140         local start=$SECONDS
16141         for i in $(seq $MDSCOUNT); do
16142                 cl_users=(${CL_USERS[mds$i]})
16143                 cl_user1[mds$i]="${cl_users[0]}"
16144                 cl_user2[mds$i]="${cl_users[1]}"
16145
16146                 [ -n "${cl_user1[mds$i]}" ] ||
16147                         error "mds$i: user1 is not registered"
16148                 [ -n "${cl_user2[mds$i]}" ] ||
16149                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16150
16151                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16152                 [ -n "$user_rec1" ] ||
16153                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16154                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16155                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16156                 [ -n "$user_rec2" ] ||
16157                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16158                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16159                      "$user_rec1 + 2 == $user_rec2"
16160                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16161                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16162                               "expected $user_rec1 + 2, but is $user_rec2"
16163                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16164                 [ -n "$user_rec2" ] ||
16165                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16166                 [ $user_rec1 == $user_rec2 ] ||
16167                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16168                               "expected $user_rec1, but is $user_rec2"
16169         done
16170
16171         # ensure we are past the previous changelog_min_gc_interval set above
16172         local sleep2=$((start + 2 - SECONDS))
16173         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16174         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16175         # cl_user1 should be OK because it recently processed records.
16176         for ((i = 0; i < MDSCOUNT; i++)); do
16177                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16178                         error "create $DIR/$tdir/d$i.3 failed"
16179         done
16180
16181         # ensure gc thread is done
16182         for i in $(mdts_nodes); do
16183                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16184                         error "$i: GC-thread not done"
16185         done
16186
16187         local first_rec
16188         for (( i = 1; i <= MDSCOUNT; i++ )); do
16189                 # check cl_user1 still registered
16190                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16191                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16192                 # check cl_user2 unregistered
16193                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16194                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16195
16196                 # check changelogs are present and starting at $user_rec1 + 1
16197                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16198                 [ -n "$user_rec1" ] ||
16199                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16200                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16201                             awk '{ print $1; exit; }')
16202
16203                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16204                 [ $((user_rec1 + 1)) == $first_rec ] ||
16205                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16206         done
16207 }
16208 run_test 160g "changelog garbage collect on idle records"
16209
16210 test_160h() {
16211         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16212         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16213                 skip "Need MDS version at least 2.10.56"
16214
16215         local mdts=$(comma_list $(mdts_nodes))
16216
16217         # Create a user
16218         changelog_register || error "first changelog_register failed"
16219         changelog_register || error "second changelog_register failed"
16220         local cl_users
16221         declare -A cl_user1
16222         declare -A cl_user2
16223         local user_rec1
16224         local user_rec2
16225         local i
16226
16227         # generate some changelog records to accumulate on each MDT
16228         # use all_char because created files should be evenly distributed
16229         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16230                 error "test_mkdir $tdir failed"
16231         for ((i = 0; i < MDSCOUNT; i++)); do
16232                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16233                         error "create $DIR/$tdir/d$i.1 failed"
16234         done
16235
16236         # check changelogs have been generated
16237         local nbcl=$(changelog_dump | wc -l)
16238         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16239
16240         for param in "changelog_max_idle_time=10" \
16241                      "changelog_gc=1" \
16242                      "changelog_min_gc_interval=2"; do
16243                 local MDT0=$(facet_svc $SINGLEMDS)
16244                 local var="${param%=*}"
16245                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16246
16247                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16248                 do_nodes $mdts $LCTL set_param mdd.*.$param
16249         done
16250
16251         # force cl_user2 to be idle (1st part)
16252         sleep 9
16253
16254         for i in $(seq $MDSCOUNT); do
16255                 cl_users=(${CL_USERS[mds$i]})
16256                 cl_user1[mds$i]="${cl_users[0]}"
16257                 cl_user2[mds$i]="${cl_users[1]}"
16258
16259                 [ -n "${cl_user1[mds$i]}" ] ||
16260                         error "mds$i: no user registered"
16261                 [ -n "${cl_user2[mds$i]}" ] ||
16262                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16263
16264                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16265                 [ -n "$user_rec1" ] ||
16266                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16267                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16268                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16269                 [ -n "$user_rec2" ] ||
16270                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16271                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16272                      "$user_rec1 + 2 == $user_rec2"
16273                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16274                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16275                               "$user_rec1 + 2, but is $user_rec2"
16276                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16277                 [ -n "$user_rec2" ] ||
16278                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16279                 [ $user_rec1 == $user_rec2 ] ||
16280                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16281                               "$user_rec1, but is $user_rec2"
16282         done
16283
16284         # force cl_user2 to be idle (2nd part) and to reach
16285         # changelog_max_idle_time
16286         sleep 2
16287
16288         # force each GC-thread start and block then
16289         # one per MDT/MDD, set fail_val accordingly
16290         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16291         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16292
16293         # generate more changelogs to trigger fail_loc
16294         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16295                 error "create $DIR/$tdir/${tfile}bis failed"
16296
16297         # stop MDT to stop GC-thread, should be done in back-ground as it will
16298         # block waiting for the thread to be released and exit
16299         declare -A stop_pids
16300         for i in $(seq $MDSCOUNT); do
16301                 stop mds$i &
16302                 stop_pids[mds$i]=$!
16303         done
16304
16305         for i in $(mdts_nodes); do
16306                 local facet
16307                 local nb=0
16308                 local facets=$(facets_up_on_host $i)
16309
16310                 for facet in ${facets//,/ }; do
16311                         if [[ $facet == mds* ]]; then
16312                                 nb=$((nb + 1))
16313                         fi
16314                 done
16315                 # ensure each MDS's gc threads are still present and all in "R"
16316                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16317                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16318                         error "$i: expected $nb GC-thread"
16319                 wait_update $i \
16320                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16321                         "R" 20 ||
16322                         error "$i: GC-thread not found in R-state"
16323                 # check umounts of each MDT on MDS have reached kthread_stop()
16324                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16325                         error "$i: expected $nb umount"
16326                 wait_update $i \
16327                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16328                         error "$i: umount not found in D-state"
16329         done
16330
16331         # release all GC-threads
16332         do_nodes $mdts $LCTL set_param fail_loc=0
16333
16334         # wait for MDT stop to complete
16335         for i in $(seq $MDSCOUNT); do
16336                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16337         done
16338
16339         # XXX
16340         # may try to check if any orphan changelog records are present
16341         # via ldiskfs/zfs and llog_reader...
16342
16343         # re-start/mount MDTs
16344         for i in $(seq $MDSCOUNT); do
16345                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16346                         error "Fail to start mds$i"
16347         done
16348
16349         local first_rec
16350         for i in $(seq $MDSCOUNT); do
16351                 # check cl_user1 still registered
16352                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16353                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16354                 # check cl_user2 unregistered
16355                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16356                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16357
16358                 # check changelogs are present and starting at $user_rec1 + 1
16359                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16360                 [ -n "$user_rec1" ] ||
16361                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16362                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16363                             awk '{ print $1; exit; }')
16364
16365                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16366                 [ $((user_rec1 + 1)) == $first_rec ] ||
16367                         error "mds$i: first index should be $user_rec1 + 1, " \
16368                               "but is $first_rec"
16369         done
16370 }
16371 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16372               "during mount"
16373
16374 test_160i() {
16375
16376         local mdts=$(comma_list $(mdts_nodes))
16377
16378         changelog_register || error "first changelog_register failed"
16379
16380         # generate some changelog records to accumulate on each MDT
16381         # use all_char because created files should be evenly distributed
16382         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16383                 error "test_mkdir $tdir failed"
16384         for ((i = 0; i < MDSCOUNT; i++)); do
16385                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16386                         error "create $DIR/$tdir/d$i.1 failed"
16387         done
16388
16389         # check changelogs have been generated
16390         local nbcl=$(changelog_dump | wc -l)
16391         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16392
16393         # simulate race between register and unregister
16394         # XXX as fail_loc is set per-MDS, with DNE configs the race
16395         # simulation will only occur for one MDT per MDS and for the
16396         # others the normal race scenario will take place
16397         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16398         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16399         do_nodes $mdts $LCTL set_param fail_val=1
16400
16401         # unregister 1st user
16402         changelog_deregister &
16403         local pid1=$!
16404         # wait some time for deregister work to reach race rdv
16405         sleep 2
16406         # register 2nd user
16407         changelog_register || error "2nd user register failed"
16408
16409         wait $pid1 || error "1st user deregister failed"
16410
16411         local i
16412         local last_rec
16413         declare -A LAST_REC
16414         for i in $(seq $MDSCOUNT); do
16415                 if changelog_users mds$i | grep "^cl"; then
16416                         # make sure new records are added with one user present
16417                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16418                                           awk '/^current.index:/ { print $NF }')
16419                 else
16420                         error "mds$i has no user registered"
16421                 fi
16422         done
16423
16424         # generate more changelog records to accumulate on each MDT
16425         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16426                 error "create $DIR/$tdir/${tfile}bis failed"
16427
16428         for i in $(seq $MDSCOUNT); do
16429                 last_rec=$(changelog_users $SINGLEMDS |
16430                            awk '/^current.index:/ { print $NF }')
16431                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16432                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16433                         error "changelogs are off on mds$i"
16434         done
16435 }
16436 run_test 160i "changelog user register/unregister race"
16437
16438 test_160j() {
16439         remote_mds_nodsh && skip "remote MDS with nodsh"
16440         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16441                 skip "Need MDS version at least 2.12.56"
16442
16443         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16444         stack_trap "umount $MOUNT2" EXIT
16445
16446         changelog_register || error "first changelog_register failed"
16447         stack_trap "changelog_deregister" EXIT
16448
16449         # generate some changelog
16450         # use all_char because created files should be evenly distributed
16451         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16452                 error "mkdir $tdir failed"
16453         for ((i = 0; i < MDSCOUNT; i++)); do
16454                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16455                         error "create $DIR/$tdir/d$i.1 failed"
16456         done
16457
16458         # open the changelog device
16459         exec 3>/dev/changelog-$FSNAME-MDT0000
16460         stack_trap "exec 3>&-" EXIT
16461         exec 4</dev/changelog-$FSNAME-MDT0000
16462         stack_trap "exec 4<&-" EXIT
16463
16464         # umount the first lustre mount
16465         umount $MOUNT
16466         stack_trap "mount_client $MOUNT" EXIT
16467
16468         # read changelog, which may or may not fail, but should not crash
16469         cat <&4 >/dev/null
16470
16471         # clear changelog
16472         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16473         changelog_users $SINGLEMDS | grep -q $cl_user ||
16474                 error "User $cl_user not found in changelog_users"
16475
16476         printf 'clear:'$cl_user':0' >&3
16477 }
16478 run_test 160j "client can be umounted while its chanangelog is being used"
16479
16480 test_160k() {
16481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16482         remote_mds_nodsh && skip "remote MDS with nodsh"
16483
16484         mkdir -p $DIR/$tdir/1/1
16485
16486         changelog_register || error "changelog_register failed"
16487         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16488
16489         changelog_users $SINGLEMDS | grep -q $cl_user ||
16490                 error "User '$cl_user' not found in changelog_users"
16491 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16492         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16493         rmdir $DIR/$tdir/1/1 & sleep 1
16494         mkdir $DIR/$tdir/2
16495         touch $DIR/$tdir/2/2
16496         rm -rf $DIR/$tdir/2
16497
16498         wait
16499         sleep 4
16500
16501         changelog_dump | grep rmdir || error "rmdir not recorded"
16502 }
16503 run_test 160k "Verify that changelog records are not lost"
16504
16505 # Verifies that a file passed as a parameter has recently had an operation
16506 # performed on it that has generated an MTIME changelog which contains the
16507 # correct parent FID. As files might reside on a different MDT from the
16508 # parent directory in DNE configurations, the FIDs are translated to paths
16509 # before being compared, which should be identical
16510 compare_mtime_changelog() {
16511         local file="${1}"
16512         local mdtidx
16513         local mtime
16514         local cl_fid
16515         local pdir
16516         local dir
16517
16518         mdtidx=$($LFS getstripe --mdt-index $file)
16519         mdtidx=$(printf "%04x" $mdtidx)
16520
16521         # Obtain the parent FID from the MTIME changelog
16522         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16523         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16524
16525         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16526         [ -z "$cl_fid" ] && error "parent FID not present"
16527
16528         # Verify that the path for the parent FID is the same as the path for
16529         # the test directory
16530         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16531
16532         dir=$(dirname $1)
16533
16534         [[ "${pdir%/}" == "$dir" ]] ||
16535                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16536 }
16537
16538 test_160l() {
16539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16540
16541         remote_mds_nodsh && skip "remote MDS with nodsh"
16542         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16543                 skip "Need MDS version at least 2.13.55"
16544
16545         local cl_user
16546
16547         changelog_register || error "changelog_register failed"
16548         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16549
16550         changelog_users $SINGLEMDS | grep -q $cl_user ||
16551                 error "User '$cl_user' not found in changelog_users"
16552
16553         # Clear some types so that MTIME changelogs are generated
16554         changelog_chmask "-CREAT"
16555         changelog_chmask "-CLOSE"
16556
16557         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16558
16559         # Test CL_MTIME during setattr
16560         touch $DIR/$tdir/$tfile
16561         compare_mtime_changelog $DIR/$tdir/$tfile
16562
16563         # Test CL_MTIME during close
16564         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16565         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16566 }
16567 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16568
16569 test_160m() {
16570         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16571         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16572                 skip "Need MDS version at least 2.14.51"
16573         local cl_users
16574         local cl_user1
16575         local cl_user2
16576         local pid1
16577
16578         # Create a user
16579         changelog_register || error "first changelog_register failed"
16580         changelog_register || error "second changelog_register failed"
16581
16582         cl_users=(${CL_USERS[mds1]})
16583         cl_user1="${cl_users[0]}"
16584         cl_user2="${cl_users[1]}"
16585         # generate some changelog records to accumulate on MDT0
16586         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16587         createmany -m $DIR/$tdir/$tfile 50 ||
16588                 error "create $DIR/$tdir/$tfile failed"
16589         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16590         rm -f $DIR/$tdir
16591
16592         # check changelogs have been generated
16593         local nbcl=$(changelog_dump | wc -l)
16594         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16595
16596 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16597         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16598
16599         __changelog_clear mds1 $cl_user1 +10
16600         __changelog_clear mds1 $cl_user2 0 &
16601         pid1=$!
16602         sleep 2
16603         __changelog_clear mds1 $cl_user1 0 ||
16604                 error "fail to cancel record for $cl_user1"
16605         wait $pid1
16606         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16607 }
16608 run_test 160m "Changelog clear race"
16609
16610 test_160n() {
16611         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16612         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16613                 skip "Need MDS version at least 2.14.51"
16614         local cl_users
16615         local cl_user1
16616         local cl_user2
16617         local pid1
16618         local first_rec
16619         local last_rec=0
16620
16621         # Create a user
16622         changelog_register || error "first changelog_register failed"
16623
16624         cl_users=(${CL_USERS[mds1]})
16625         cl_user1="${cl_users[0]}"
16626
16627         # generate some changelog records to accumulate on MDT0
16628         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16629         first_rec=$(changelog_users $SINGLEMDS |
16630                         awk '/^current.index:/ { print $NF }')
16631         while (( last_rec < (( first_rec + 65000)) )); do
16632                 createmany -m $DIR/$tdir/$tfile 10000 ||
16633                         error "create $DIR/$tdir/$tfile failed"
16634
16635                 for i in $(seq 0 10000); do
16636                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16637                                 > /dev/null
16638                 done
16639
16640                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16641                         error "unlinkmany failed unlink"
16642                 last_rec=$(changelog_users $SINGLEMDS |
16643                         awk '/^current.index:/ { print $NF }')
16644                 echo last record $last_rec
16645                 (( last_rec == 0 )) && error "no changelog found"
16646         done
16647
16648 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16649         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16650
16651         __changelog_clear mds1 $cl_user1 0 &
16652         pid1=$!
16653         sleep 2
16654         __changelog_clear mds1 $cl_user1 0 ||
16655                 error "fail to cancel record for $cl_user1"
16656         wait $pid1
16657         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16658 }
16659 run_test 160n "Changelog destroy race"
16660
16661 test_160o() {
16662         local mdt="$(facet_svc $SINGLEMDS)"
16663
16664         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16665         remote_mds_nodsh && skip "remote MDS with nodsh"
16666         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16667                 skip "Need MDS version at least 2.14.52"
16668
16669         changelog_register --user test_160o -m unlnk+close+open ||
16670                 error "changelog_register failed"
16671
16672         do_facet $SINGLEMDS $LCTL --device $mdt \
16673                                 changelog_register -u "Tt3_-#" &&
16674                 error "bad symbols in name should fail"
16675
16676         do_facet $SINGLEMDS $LCTL --device $mdt \
16677                                 changelog_register -u test_160o &&
16678                 error "the same name registration should fail"
16679
16680         do_facet $SINGLEMDS $LCTL --device $mdt \
16681                         changelog_register -u test_160toolongname &&
16682                 error "too long name registration should fail"
16683
16684         changelog_chmask "MARK+HSM"
16685         lctl get_param mdd.*.changelog*mask
16686         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16687         changelog_users $SINGLEMDS | grep -q $cl_user ||
16688                 error "User $cl_user not found in changelog_users"
16689         #verify username
16690         echo $cl_user | grep -q test_160o ||
16691                 error "User $cl_user has no specific name 'test160o'"
16692
16693         # change something
16694         changelog_clear 0 || error "changelog_clear failed"
16695         # generate some changelog records to accumulate on MDT0
16696         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16697         touch $DIR/$tdir/$tfile                 # open 1
16698
16699         OPENS=$(changelog_dump | grep -c "OPEN")
16700         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16701
16702         # must be no MKDIR it wasn't set as user mask
16703         MKDIR=$(changelog_dump | grep -c "MKDIR")
16704         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16705
16706         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16707                                 mdd.$mdt.changelog_current_mask -n)
16708         # register maskless user
16709         changelog_register || error "changelog_register failed"
16710         # effective mask should be not changed because it is not minimal
16711         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16712                                 mdd.$mdt.changelog_current_mask -n)
16713         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16714         # set server mask to minimal value
16715         changelog_chmask "MARK"
16716         # check effective mask again, should be treated as DEFMASK now
16717         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16718                                 mdd.$mdt.changelog_current_mask -n)
16719         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16720
16721         do_facet $SINGLEMDS $LCTL --device $mdt \
16722                                 changelog_deregister -u test_160o ||
16723                 error "cannot deregister by name"
16724 }
16725 run_test 160o "changelog user name and mask"
16726
16727 test_160p() {
16728         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16729         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16730                 skip "Need MDS version at least 2.14.51"
16731         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16732         local cl_users
16733         local cl_user1
16734         local entry_count
16735
16736         # Create a user
16737         changelog_register || error "first changelog_register failed"
16738
16739         cl_users=(${CL_USERS[mds1]})
16740         cl_user1="${cl_users[0]}"
16741
16742         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16743         createmany -m $DIR/$tdir/$tfile 50 ||
16744                 error "create $DIR/$tdir/$tfile failed"
16745         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16746         rm -rf $DIR/$tdir
16747
16748         # check changelogs have been generated
16749         entry_count=$(changelog_dump | wc -l)
16750         ((entry_count != 0)) || error "no changelog entries found"
16751
16752         # remove changelog_users and check that orphan entries are removed
16753         stop mds1
16754         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16755         start mds1 || error "cannot start mdt"
16756         entry_count=$(changelog_dump | wc -l)
16757         ((entry_count == 0)) ||
16758                 error "found $entry_count changelog entries, expected none"
16759 }
16760 run_test 160p "Changelog orphan cleanup with no users"
16761
16762 test_160q() {
16763         local mdt="$(facet_svc $SINGLEMDS)"
16764         local clu
16765
16766         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16767         remote_mds_nodsh && skip "remote MDS with nodsh"
16768         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16769                 skip "Need MDS version at least 2.14.54"
16770
16771         # set server mask to minimal value like server init does
16772         changelog_chmask "MARK"
16773         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16774                 error "changelog_register failed"
16775         # check effective mask again, should be treated as DEFMASK now
16776         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16777                                 mdd.$mdt.changelog_current_mask -n)
16778         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16779                 error "changelog_deregister failed"
16780         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16781 }
16782 run_test 160q "changelog effective mask is DEFMASK if not set"
16783
16784 test_160s() {
16785         remote_mds_nodsh && skip "remote MDS with nodsh"
16786         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16787                 skip "Need MDS version at least 2.14.55"
16788
16789         local mdts=$(comma_list $(mdts_nodes))
16790
16791         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16792         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16793                                        fail_val=$((24 * 3600 * 10))
16794
16795         # Create a user which is 10 days old
16796         changelog_register || error "first changelog_register failed"
16797         local cl_users
16798         declare -A cl_user1
16799         local i
16800
16801         # generate some changelog records to accumulate on each MDT
16802         # use all_char because created files should be evenly distributed
16803         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16804                 error "test_mkdir $tdir failed"
16805         for ((i = 0; i < MDSCOUNT; i++)); do
16806                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16807                         error "create $DIR/$tdir/d$i.1 failed"
16808         done
16809
16810         # check changelogs have been generated
16811         local nbcl=$(changelog_dump | wc -l)
16812         (( nbcl > 0 )) || error "no changelogs found"
16813
16814         # reduce the max_idle_indexes value to make sure we exceed it
16815         for param in "changelog_max_idle_indexes=2097446912" \
16816                      "changelog_max_idle_time=2592000" \
16817                      "changelog_gc=1" \
16818                      "changelog_min_gc_interval=2"; do
16819                 local MDT0=$(facet_svc $SINGLEMDS)
16820                 local var="${param%=*}"
16821                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16822
16823                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16824                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16825                         error "unable to set mdd.*.$param"
16826         done
16827
16828         local start=$SECONDS
16829         for i in $(seq $MDSCOUNT); do
16830                 cl_users=(${CL_USERS[mds$i]})
16831                 cl_user1[mds$i]="${cl_users[0]}"
16832
16833                 [[ -n "${cl_user1[mds$i]}" ]] ||
16834                         error "mds$i: no user registered"
16835         done
16836
16837         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16838         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16839
16840         # ensure we are past the previous changelog_min_gc_interval set above
16841         local sleep2=$((start + 2 - SECONDS))
16842         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16843
16844         # Generate one more changelog to trigger GC
16845         for ((i = 0; i < MDSCOUNT; i++)); do
16846                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16847                         error "create $DIR/$tdir/d$i.3 failed"
16848         done
16849
16850         # ensure gc thread is done
16851         for node in $(mdts_nodes); do
16852                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16853                         error "$node: GC-thread not done"
16854         done
16855
16856         do_nodes $mdts $LCTL set_param fail_loc=0
16857
16858         for (( i = 1; i <= MDSCOUNT; i++ )); do
16859                 # check cl_user1 is purged
16860                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16861                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16862         done
16863         return 0
16864 }
16865 run_test 160s "changelog garbage collect on idle records * time"
16866
16867 test_161a() {
16868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16869
16870         test_mkdir -c1 $DIR/$tdir
16871         cp /etc/hosts $DIR/$tdir/$tfile
16872         test_mkdir -c1 $DIR/$tdir/foo1
16873         test_mkdir -c1 $DIR/$tdir/foo2
16874         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16875         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16876         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16877         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16878         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16879         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16880                 $LFS fid2path $DIR $FID
16881                 error "bad link ea"
16882         fi
16883         # middle
16884         rm $DIR/$tdir/foo2/zachary
16885         # last
16886         rm $DIR/$tdir/foo2/thor
16887         # first
16888         rm $DIR/$tdir/$tfile
16889         # rename
16890         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16891         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16892                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16893         rm $DIR/$tdir/foo2/maggie
16894
16895         # overflow the EA
16896         local longname=$tfile.avg_len_is_thirty_two_
16897         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16898                 error_noexit 'failed to unlink many hardlinks'" EXIT
16899         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16900                 error "failed to hardlink many files"
16901         links=$($LFS fid2path $DIR $FID | wc -l)
16902         echo -n "${links}/1000 links in link EA"
16903         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16904 }
16905 run_test 161a "link ea sanity"
16906
16907 test_161b() {
16908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16909         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16910
16911         local MDTIDX=1
16912         local remote_dir=$DIR/$tdir/remote_dir
16913
16914         mkdir -p $DIR/$tdir
16915         $LFS mkdir -i $MDTIDX $remote_dir ||
16916                 error "create remote directory failed"
16917
16918         cp /etc/hosts $remote_dir/$tfile
16919         mkdir -p $remote_dir/foo1
16920         mkdir -p $remote_dir/foo2
16921         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16922         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16923         ln $remote_dir/$tfile $remote_dir/foo1/luna
16924         ln $remote_dir/$tfile $remote_dir/foo2/thor
16925
16926         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16927                      tr -d ']')
16928         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16929                 $LFS fid2path $DIR $FID
16930                 error "bad link ea"
16931         fi
16932         # middle
16933         rm $remote_dir/foo2/zachary
16934         # last
16935         rm $remote_dir/foo2/thor
16936         # first
16937         rm $remote_dir/$tfile
16938         # rename
16939         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16940         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16941         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16942                 $LFS fid2path $DIR $FID
16943                 error "bad link rename"
16944         fi
16945         rm $remote_dir/foo2/maggie
16946
16947         # overflow the EA
16948         local longname=filename_avg_len_is_thirty_two_
16949         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16950                 error "failed to hardlink many files"
16951         links=$($LFS fid2path $DIR $FID | wc -l)
16952         echo -n "${links}/1000 links in link EA"
16953         [[ ${links} -gt 60 ]] ||
16954                 error "expected at least 60 links in link EA"
16955         unlinkmany $remote_dir/foo2/$longname 1000 ||
16956         error "failed to unlink many hardlinks"
16957 }
16958 run_test 161b "link ea sanity under remote directory"
16959
16960 test_161c() {
16961         remote_mds_nodsh && skip "remote MDS with nodsh"
16962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16963         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16964                 skip "Need MDS version at least 2.1.5"
16965
16966         # define CLF_RENAME_LAST 0x0001
16967         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16968         changelog_register || error "changelog_register failed"
16969
16970         rm -rf $DIR/$tdir
16971         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16972         touch $DIR/$tdir/foo_161c
16973         touch $DIR/$tdir/bar_161c
16974         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16975         changelog_dump | grep RENME | tail -n 5
16976         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16977         changelog_clear 0 || error "changelog_clear failed"
16978         if [ x$flags != "x0x1" ]; then
16979                 error "flag $flags is not 0x1"
16980         fi
16981
16982         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16983         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16984         touch $DIR/$tdir/foo_161c
16985         touch $DIR/$tdir/bar_161c
16986         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16987         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16988         changelog_dump | grep RENME | tail -n 5
16989         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16990         changelog_clear 0 || error "changelog_clear failed"
16991         if [ x$flags != "x0x0" ]; then
16992                 error "flag $flags is not 0x0"
16993         fi
16994         echo "rename overwrite a target having nlink > 1," \
16995                 "changelog record has flags of $flags"
16996
16997         # rename doesn't overwrite a target (changelog flag 0x0)
16998         touch $DIR/$tdir/foo_161c
16999         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17000         changelog_dump | grep RENME | tail -n 5
17001         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17002         changelog_clear 0 || error "changelog_clear failed"
17003         if [ x$flags != "x0x0" ]; then
17004                 error "flag $flags is not 0x0"
17005         fi
17006         echo "rename doesn't overwrite a target," \
17007                 "changelog record has flags of $flags"
17008
17009         # define CLF_UNLINK_LAST 0x0001
17010         # unlink a file having nlink = 1 (changelog flag 0x1)
17011         rm -f $DIR/$tdir/foo2_161c
17012         changelog_dump | grep UNLNK | tail -n 5
17013         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17014         changelog_clear 0 || error "changelog_clear failed"
17015         if [ x$flags != "x0x1" ]; then
17016                 error "flag $flags is not 0x1"
17017         fi
17018         echo "unlink a file having nlink = 1," \
17019                 "changelog record has flags of $flags"
17020
17021         # unlink a file having nlink > 1 (changelog flag 0x0)
17022         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17023         rm -f $DIR/$tdir/foobar_161c
17024         changelog_dump | grep UNLNK | tail -n 5
17025         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17026         changelog_clear 0 || error "changelog_clear failed"
17027         if [ x$flags != "x0x0" ]; then
17028                 error "flag $flags is not 0x0"
17029         fi
17030         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17031 }
17032 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17033
17034 test_161d() {
17035         remote_mds_nodsh && skip "remote MDS with nodsh"
17036         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17037
17038         local pid
17039         local fid
17040
17041         changelog_register || error "changelog_register failed"
17042
17043         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17044         # interfer with $MOUNT/.lustre/fid/ access
17045         mkdir $DIR/$tdir
17046         [[ $? -eq 0 ]] || error "mkdir failed"
17047
17048         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17049         $LCTL set_param fail_loc=0x8000140c
17050         # 5s pause
17051         $LCTL set_param fail_val=5
17052
17053         # create file
17054         echo foofoo > $DIR/$tdir/$tfile &
17055         pid=$!
17056
17057         # wait for create to be delayed
17058         sleep 2
17059
17060         ps -p $pid
17061         [[ $? -eq 0 ]] || error "create should be blocked"
17062
17063         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17064         stack_trap "rm -f $tempfile"
17065         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17066         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17067         # some delay may occur during ChangeLog publishing and file read just
17068         # above, that could allow file write to happen finally
17069         [[ -s $tempfile ]] && echo "file should be empty"
17070
17071         $LCTL set_param fail_loc=0
17072
17073         wait $pid
17074         [[ $? -eq 0 ]] || error "create failed"
17075 }
17076 run_test 161d "create with concurrent .lustre/fid access"
17077
17078 check_path() {
17079         local expected="$1"
17080         shift
17081         local fid="$2"
17082
17083         local path
17084         path=$($LFS fid2path "$@")
17085         local rc=$?
17086
17087         if [ $rc -ne 0 ]; then
17088                 error "path looked up of '$expected' failed: rc=$rc"
17089         elif [ "$path" != "$expected" ]; then
17090                 error "path looked up '$path' instead of '$expected'"
17091         else
17092                 echo "FID '$fid' resolves to path '$path' as expected"
17093         fi
17094 }
17095
17096 test_162a() { # was test_162
17097         test_mkdir -p -c1 $DIR/$tdir/d2
17098         touch $DIR/$tdir/d2/$tfile
17099         touch $DIR/$tdir/d2/x1
17100         touch $DIR/$tdir/d2/x2
17101         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17102         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17103         # regular file
17104         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17105         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17106
17107         # softlink
17108         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17109         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17110         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17111
17112         # softlink to wrong file
17113         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17114         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17115         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17116
17117         # hardlink
17118         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17119         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17120         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17121         # fid2path dir/fsname should both work
17122         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17123         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17124
17125         # hardlink count: check that there are 2 links
17126         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17127         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17128
17129         # hardlink indexing: remove the first link
17130         rm $DIR/$tdir/d2/p/q/r/hlink
17131         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17132 }
17133 run_test 162a "path lookup sanity"
17134
17135 test_162b() {
17136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17137         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17138
17139         mkdir $DIR/$tdir
17140         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17141                                 error "create striped dir failed"
17142
17143         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17144                                         tail -n 1 | awk '{print $2}')
17145         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17146
17147         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17148         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17149
17150         # regular file
17151         for ((i=0;i<5;i++)); do
17152                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17153                         error "get fid for f$i failed"
17154                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17155
17156                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17157                         error "get fid for d$i failed"
17158                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17159         done
17160
17161         return 0
17162 }
17163 run_test 162b "striped directory path lookup sanity"
17164
17165 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17166 test_162c() {
17167         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17168                 skip "Need MDS version at least 2.7.51"
17169
17170         local lpath=$tdir.local
17171         local rpath=$tdir.remote
17172
17173         test_mkdir $DIR/$lpath
17174         test_mkdir $DIR/$rpath
17175
17176         for ((i = 0; i <= 101; i++)); do
17177                 lpath="$lpath/$i"
17178                 mkdir $DIR/$lpath
17179                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17180                         error "get fid for local directory $DIR/$lpath failed"
17181                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17182
17183                 rpath="$rpath/$i"
17184                 test_mkdir $DIR/$rpath
17185                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17186                         error "get fid for remote directory $DIR/$rpath failed"
17187                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17188         done
17189
17190         return 0
17191 }
17192 run_test 162c "fid2path works with paths 100 or more directories deep"
17193
17194 oalr_event_count() {
17195         local event="${1}"
17196         local trace="${2}"
17197
17198         awk -v name="${FSNAME}-OST0000" \
17199             -v event="${event}" \
17200             '$1 == "TRACE" && $2 == event && $3 == name' \
17201             "${trace}" |
17202         wc -l
17203 }
17204
17205 oalr_expect_event_count() {
17206         local event="${1}"
17207         local trace="${2}"
17208         local expect="${3}"
17209         local count
17210
17211         count=$(oalr_event_count "${event}" "${trace}")
17212         if ((count == expect)); then
17213                 return 0
17214         fi
17215
17216         error_noexit "${event} event count was '${count}', expected ${expect}"
17217         cat "${trace}" >&2
17218         exit 1
17219 }
17220
17221 cleanup_165() {
17222         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17223         stop ost1
17224         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17225 }
17226
17227 setup_165() {
17228         sync # Flush previous IOs so we can count log entries.
17229         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17230         stack_trap cleanup_165 EXIT
17231 }
17232
17233 test_165a() {
17234         local trace="/tmp/${tfile}.trace"
17235         local rc
17236         local count
17237
17238         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17239                 skip "OFD access log unsupported"
17240
17241         setup_165
17242         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17243         sleep 5
17244
17245         do_facet ost1 ofd_access_log_reader --list
17246         stop ost1
17247
17248         do_facet ost1 killall -TERM ofd_access_log_reader
17249         wait
17250         rc=$?
17251
17252         if ((rc != 0)); then
17253                 error "ofd_access_log_reader exited with rc = '${rc}'"
17254         fi
17255
17256         # Parse trace file for discovery events:
17257         oalr_expect_event_count alr_log_add "${trace}" 1
17258         oalr_expect_event_count alr_log_eof "${trace}" 1
17259         oalr_expect_event_count alr_log_free "${trace}" 1
17260 }
17261 run_test 165a "ofd access log discovery"
17262
17263 test_165b() {
17264         local trace="/tmp/${tfile}.trace"
17265         local file="${DIR}/${tfile}"
17266         local pfid1
17267         local pfid2
17268         local -a entry
17269         local rc
17270         local count
17271         local size
17272         local flags
17273
17274         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17275                 skip "OFD access log unsupported"
17276
17277         setup_165
17278         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17279         sleep 5
17280
17281         do_facet ost1 ofd_access_log_reader --list
17282
17283         lfs setstripe -c 1 -i 0 "${file}"
17284         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17285                 error "cannot create '${file}'"
17286
17287         sleep 5
17288         do_facet ost1 killall -TERM ofd_access_log_reader
17289         wait
17290         rc=$?
17291
17292         if ((rc != 0)); then
17293                 error "ofd_access_log_reader exited with rc = '${rc}'"
17294         fi
17295
17296         oalr_expect_event_count alr_log_entry "${trace}" 1
17297
17298         pfid1=$($LFS path2fid "${file}")
17299
17300         # 1     2             3   4    5     6   7    8    9     10
17301         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17302         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17303
17304         echo "entry = '${entry[*]}'" >&2
17305
17306         pfid2=${entry[4]}
17307         if [[ "${pfid1}" != "${pfid2}" ]]; then
17308                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17309         fi
17310
17311         size=${entry[8]}
17312         if ((size != 1048576)); then
17313                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17314         fi
17315
17316         flags=${entry[10]}
17317         if [[ "${flags}" != "w" ]]; then
17318                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17319         fi
17320
17321         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17322         sleep 5
17323
17324         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17325                 error "cannot read '${file}'"
17326         sleep 5
17327
17328         do_facet ost1 killall -TERM ofd_access_log_reader
17329         wait
17330         rc=$?
17331
17332         if ((rc != 0)); then
17333                 error "ofd_access_log_reader exited with rc = '${rc}'"
17334         fi
17335
17336         oalr_expect_event_count alr_log_entry "${trace}" 1
17337
17338         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17339         echo "entry = '${entry[*]}'" >&2
17340
17341         pfid2=${entry[4]}
17342         if [[ "${pfid1}" != "${pfid2}" ]]; then
17343                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17344         fi
17345
17346         size=${entry[8]}
17347         if ((size != 524288)); then
17348                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17349         fi
17350
17351         flags=${entry[10]}
17352         if [[ "${flags}" != "r" ]]; then
17353                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17354         fi
17355 }
17356 run_test 165b "ofd access log entries are produced and consumed"
17357
17358 test_165c() {
17359         local trace="/tmp/${tfile}.trace"
17360         local file="${DIR}/${tdir}/${tfile}"
17361
17362         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17363                 skip "OFD access log unsupported"
17364
17365         test_mkdir "${DIR}/${tdir}"
17366
17367         setup_165
17368         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17369         sleep 5
17370
17371         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17372
17373         # 4096 / 64 = 64. Create twice as many entries.
17374         for ((i = 0; i < 128; i++)); do
17375                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17376                         error "cannot create file"
17377         done
17378
17379         sync
17380
17381         do_facet ost1 killall -TERM ofd_access_log_reader
17382         wait
17383         rc=$?
17384         if ((rc != 0)); then
17385                 error "ofd_access_log_reader exited with rc = '${rc}'"
17386         fi
17387
17388         unlinkmany  "${file}-%d" 128
17389 }
17390 run_test 165c "full ofd access logs do not block IOs"
17391
17392 oal_get_read_count() {
17393         local stats="$1"
17394
17395         # STATS lustre-OST0001 alr_read_count 1
17396
17397         do_facet ost1 cat "${stats}" |
17398         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17399              END { print count; }'
17400 }
17401
17402 oal_expect_read_count() {
17403         local stats="$1"
17404         local count
17405         local expect="$2"
17406
17407         # Ask ofd_access_log_reader to write stats.
17408         do_facet ost1 killall -USR1 ofd_access_log_reader
17409
17410         # Allow some time for things to happen.
17411         sleep 1
17412
17413         count=$(oal_get_read_count "${stats}")
17414         if ((count == expect)); then
17415                 return 0
17416         fi
17417
17418         error_noexit "bad read count, got ${count}, expected ${expect}"
17419         do_facet ost1 cat "${stats}" >&2
17420         exit 1
17421 }
17422
17423 test_165d() {
17424         local stats="/tmp/${tfile}.stats"
17425         local file="${DIR}/${tdir}/${tfile}"
17426         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17427
17428         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17429                 skip "OFD access log unsupported"
17430
17431         test_mkdir "${DIR}/${tdir}"
17432
17433         setup_165
17434         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17435         sleep 5
17436
17437         lfs setstripe -c 1 -i 0 "${file}"
17438
17439         do_facet ost1 lctl set_param "${param}=rw"
17440         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17441                 error "cannot create '${file}'"
17442         oal_expect_read_count "${stats}" 1
17443
17444         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17445                 error "cannot read '${file}'"
17446         oal_expect_read_count "${stats}" 2
17447
17448         do_facet ost1 lctl set_param "${param}=r"
17449         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17450                 error "cannot create '${file}'"
17451         oal_expect_read_count "${stats}" 2
17452
17453         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17454                 error "cannot read '${file}'"
17455         oal_expect_read_count "${stats}" 3
17456
17457         do_facet ost1 lctl set_param "${param}=w"
17458         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17459                 error "cannot create '${file}'"
17460         oal_expect_read_count "${stats}" 4
17461
17462         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17463                 error "cannot read '${file}'"
17464         oal_expect_read_count "${stats}" 4
17465
17466         do_facet ost1 lctl set_param "${param}=0"
17467         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17468                 error "cannot create '${file}'"
17469         oal_expect_read_count "${stats}" 4
17470
17471         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17472                 error "cannot read '${file}'"
17473         oal_expect_read_count "${stats}" 4
17474
17475         do_facet ost1 killall -TERM ofd_access_log_reader
17476         wait
17477         rc=$?
17478         if ((rc != 0)); then
17479                 error "ofd_access_log_reader exited with rc = '${rc}'"
17480         fi
17481 }
17482 run_test 165d "ofd_access_log mask works"
17483
17484 test_165e() {
17485         local stats="/tmp/${tfile}.stats"
17486         local file0="${DIR}/${tdir}-0/${tfile}"
17487         local file1="${DIR}/${tdir}-1/${tfile}"
17488
17489         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17490                 skip "OFD access log unsupported"
17491
17492         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17493
17494         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17495         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17496
17497         lfs setstripe -c 1 -i 0 "${file0}"
17498         lfs setstripe -c 1 -i 0 "${file1}"
17499
17500         setup_165
17501         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17502         sleep 5
17503
17504         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17505                 error "cannot create '${file0}'"
17506         sync
17507         oal_expect_read_count "${stats}" 0
17508
17509         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17510                 error "cannot create '${file1}'"
17511         sync
17512         oal_expect_read_count "${stats}" 1
17513
17514         do_facet ost1 killall -TERM ofd_access_log_reader
17515         wait
17516         rc=$?
17517         if ((rc != 0)); then
17518                 error "ofd_access_log_reader exited with rc = '${rc}'"
17519         fi
17520 }
17521 run_test 165e "ofd_access_log MDT index filter works"
17522
17523 test_165f() {
17524         local trace="/tmp/${tfile}.trace"
17525         local rc
17526         local count
17527
17528         setup_165
17529         do_facet ost1 timeout 60 ofd_access_log_reader \
17530                 --exit-on-close --debug=- --trace=- > "${trace}" &
17531         sleep 5
17532         stop ost1
17533
17534         wait
17535         rc=$?
17536
17537         if ((rc != 0)); then
17538                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17539                 cat "${trace}"
17540                 exit 1
17541         fi
17542 }
17543 run_test 165f "ofd_access_log_reader --exit-on-close works"
17544
17545 test_169() {
17546         # do directio so as not to populate the page cache
17547         log "creating a 10 Mb file"
17548         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17549                 error "multiop failed while creating a file"
17550         log "starting reads"
17551         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17552         log "truncating the file"
17553         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17554                 error "multiop failed while truncating the file"
17555         log "killing dd"
17556         kill %+ || true # reads might have finished
17557         echo "wait until dd is finished"
17558         wait
17559         log "removing the temporary file"
17560         rm -rf $DIR/$tfile || error "tmp file removal failed"
17561 }
17562 run_test 169 "parallel read and truncate should not deadlock"
17563
17564 test_170() {
17565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17566
17567         $LCTL clear     # bug 18514
17568         $LCTL debug_daemon start $TMP/${tfile}_log_good
17569         touch $DIR/$tfile
17570         $LCTL debug_daemon stop
17571         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17572                 error "sed failed to read log_good"
17573
17574         $LCTL debug_daemon start $TMP/${tfile}_log_good
17575         rm -rf $DIR/$tfile
17576         $LCTL debug_daemon stop
17577
17578         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17579                error "lctl df log_bad failed"
17580
17581         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17582         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17583
17584         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17585         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17586
17587         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17588                 error "bad_line good_line1 good_line2 are empty"
17589
17590         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17591         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17592         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17593
17594         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17595         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17596         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17597
17598         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17599                 error "bad_line_new good_line_new are empty"
17600
17601         local expected_good=$((good_line1 + good_line2*2))
17602
17603         rm -f $TMP/${tfile}*
17604         # LU-231, short malformed line may not be counted into bad lines
17605         if [ $bad_line -ne $bad_line_new ] &&
17606                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17607                 error "expected $bad_line bad lines, but got $bad_line_new"
17608                 return 1
17609         fi
17610
17611         if [ $expected_good -ne $good_line_new ]; then
17612                 error "expected $expected_good good lines, but got $good_line_new"
17613                 return 2
17614         fi
17615         true
17616 }
17617 run_test 170 "test lctl df to handle corrupted log ====================="
17618
17619 test_171() { # bug20592
17620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17621
17622         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17623         $LCTL set_param fail_loc=0x50e
17624         $LCTL set_param fail_val=3000
17625         multiop_bg_pause $DIR/$tfile O_s || true
17626         local MULTIPID=$!
17627         kill -USR1 $MULTIPID
17628         # cause log dump
17629         sleep 3
17630         wait $MULTIPID
17631         if dmesg | grep "recursive fault"; then
17632                 error "caught a recursive fault"
17633         fi
17634         $LCTL set_param fail_loc=0
17635         true
17636 }
17637 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17638
17639 # it would be good to share it with obdfilter-survey/iokit-libecho code
17640 setup_obdecho_osc () {
17641         local rc=0
17642         local ost_nid=$1
17643         local obdfilter_name=$2
17644         echo "Creating new osc for $obdfilter_name on $ost_nid"
17645         # make sure we can find loopback nid
17646         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17647
17648         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17649                            ${obdfilter_name}_osc_UUID || rc=2; }
17650         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17651                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17652         return $rc
17653 }
17654
17655 cleanup_obdecho_osc () {
17656         local obdfilter_name=$1
17657         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17658         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17659         return 0
17660 }
17661
17662 obdecho_test() {
17663         local OBD=$1
17664         local node=$2
17665         local pages=${3:-64}
17666         local rc=0
17667         local id
17668
17669         local count=10
17670         local obd_size=$(get_obd_size $node $OBD)
17671         local page_size=$(get_page_size $node)
17672         if [[ -n "$obd_size" ]]; then
17673                 local new_count=$((obd_size / (pages * page_size / 1024)))
17674                 [[ $new_count -ge $count ]] || count=$new_count
17675         fi
17676
17677         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17678         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17679                            rc=2; }
17680         if [ $rc -eq 0 ]; then
17681             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17682             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17683         fi
17684         echo "New object id is $id"
17685         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17686                            rc=4; }
17687         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17688                            "test_brw $count w v $pages $id" || rc=4; }
17689         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17690                            rc=4; }
17691         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17692                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17693         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17694                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17695         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17696         return $rc
17697 }
17698
17699 test_180a() {
17700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17701
17702         if ! [ -d /sys/fs/lustre/echo_client ] &&
17703            ! module_loaded obdecho; then
17704                 load_module obdecho/obdecho &&
17705                         stack_trap "rmmod obdecho" EXIT ||
17706                         error "unable to load obdecho on client"
17707         fi
17708
17709         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17710         local host=$($LCTL get_param -n osc.$osc.import |
17711                      awk '/current_connection:/ { print $2 }' )
17712         local target=$($LCTL get_param -n osc.$osc.import |
17713                        awk '/target:/ { print $2 }' )
17714         target=${target%_UUID}
17715
17716         if [ -n "$target" ]; then
17717                 setup_obdecho_osc $host $target &&
17718                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17719                         { error "obdecho setup failed with $?"; return; }
17720
17721                 obdecho_test ${target}_osc client ||
17722                         error "obdecho_test failed on ${target}_osc"
17723         else
17724                 $LCTL get_param osc.$osc.import
17725                 error "there is no osc.$osc.import target"
17726         fi
17727 }
17728 run_test 180a "test obdecho on osc"
17729
17730 test_180b() {
17731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17732         remote_ost_nodsh && skip "remote OST with nodsh"
17733
17734         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17735                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17736                 error "failed to load module obdecho"
17737
17738         local target=$(do_facet ost1 $LCTL dl |
17739                        awk '/obdfilter/ { print $4; exit; }')
17740
17741         if [ -n "$target" ]; then
17742                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17743         else
17744                 do_facet ost1 $LCTL dl
17745                 error "there is no obdfilter target on ost1"
17746         fi
17747 }
17748 run_test 180b "test obdecho directly on obdfilter"
17749
17750 test_180c() { # LU-2598
17751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17752         remote_ost_nodsh && skip "remote OST with nodsh"
17753         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17754                 skip "Need MDS version at least 2.4.0"
17755
17756         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17757                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17758                 error "failed to load module obdecho"
17759
17760         local target=$(do_facet ost1 $LCTL dl |
17761                        awk '/obdfilter/ { print $4; exit; }')
17762
17763         if [ -n "$target" ]; then
17764                 local pages=16384 # 64MB bulk I/O RPC size
17765
17766                 obdecho_test "$target" ost1 "$pages" ||
17767                         error "obdecho_test with pages=$pages failed with $?"
17768         else
17769                 do_facet ost1 $LCTL dl
17770                 error "there is no obdfilter target on ost1"
17771         fi
17772 }
17773 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17774
17775 test_181() { # bug 22177
17776         test_mkdir $DIR/$tdir
17777         # create enough files to index the directory
17778         createmany -o $DIR/$tdir/foobar 4000
17779         # print attributes for debug purpose
17780         lsattr -d .
17781         # open dir
17782         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17783         MULTIPID=$!
17784         # remove the files & current working dir
17785         unlinkmany $DIR/$tdir/foobar 4000
17786         rmdir $DIR/$tdir
17787         kill -USR1 $MULTIPID
17788         wait $MULTIPID
17789         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17790         return 0
17791 }
17792 run_test 181 "Test open-unlinked dir ========================"
17793
17794 test_182() {
17795         local fcount=1000
17796         local tcount=10
17797
17798         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17799
17800         $LCTL set_param mdc.*.rpc_stats=clear
17801
17802         for (( i = 0; i < $tcount; i++ )) ; do
17803                 mkdir $DIR/$tdir/$i
17804         done
17805
17806         for (( i = 0; i < $tcount; i++ )) ; do
17807                 createmany -o $DIR/$tdir/$i/f- $fcount &
17808         done
17809         wait
17810
17811         for (( i = 0; i < $tcount; i++ )) ; do
17812                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17813         done
17814         wait
17815
17816         $LCTL get_param mdc.*.rpc_stats
17817
17818         rm -rf $DIR/$tdir
17819 }
17820 run_test 182 "Test parallel modify metadata operations ================"
17821
17822 test_183() { # LU-2275
17823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17824         remote_mds_nodsh && skip "remote MDS with nodsh"
17825         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17826                 skip "Need MDS version at least 2.3.56"
17827
17828         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17829         echo aaa > $DIR/$tdir/$tfile
17830
17831 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17832         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17833
17834         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17835         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17836
17837         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17838
17839         # Flush negative dentry cache
17840         touch $DIR/$tdir/$tfile
17841
17842         # We are not checking for any leaked references here, they'll
17843         # become evident next time we do cleanup with module unload.
17844         rm -rf $DIR/$tdir
17845 }
17846 run_test 183 "No crash or request leak in case of strange dispositions ========"
17847
17848 # test suite 184 is for LU-2016, LU-2017
17849 test_184a() {
17850         check_swap_layouts_support
17851
17852         dir0=$DIR/$tdir/$testnum
17853         test_mkdir -p -c1 $dir0
17854         ref1=/etc/passwd
17855         ref2=/etc/group
17856         file1=$dir0/f1
17857         file2=$dir0/f2
17858         $LFS setstripe -c1 $file1
17859         cp $ref1 $file1
17860         $LFS setstripe -c2 $file2
17861         cp $ref2 $file2
17862         gen1=$($LFS getstripe -g $file1)
17863         gen2=$($LFS getstripe -g $file2)
17864
17865         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17866         gen=$($LFS getstripe -g $file1)
17867         [[ $gen1 != $gen ]] ||
17868                 error "Layout generation on $file1 does not change"
17869         gen=$($LFS getstripe -g $file2)
17870         [[ $gen2 != $gen ]] ||
17871                 error "Layout generation on $file2 does not change"
17872
17873         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17874         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17875
17876         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17877 }
17878 run_test 184a "Basic layout swap"
17879
17880 test_184b() {
17881         check_swap_layouts_support
17882
17883         dir0=$DIR/$tdir/$testnum
17884         mkdir -p $dir0 || error "creating dir $dir0"
17885         file1=$dir0/f1
17886         file2=$dir0/f2
17887         file3=$dir0/f3
17888         dir1=$dir0/d1
17889         dir2=$dir0/d2
17890         mkdir $dir1 $dir2
17891         $LFS setstripe -c1 $file1
17892         $LFS setstripe -c2 $file2
17893         $LFS setstripe -c1 $file3
17894         chown $RUNAS_ID $file3
17895         gen1=$($LFS getstripe -g $file1)
17896         gen2=$($LFS getstripe -g $file2)
17897
17898         $LFS swap_layouts $dir1 $dir2 &&
17899                 error "swap of directories layouts should fail"
17900         $LFS swap_layouts $dir1 $file1 &&
17901                 error "swap of directory and file layouts should fail"
17902         $RUNAS $LFS swap_layouts $file1 $file2 &&
17903                 error "swap of file we cannot write should fail"
17904         $LFS swap_layouts $file1 $file3 &&
17905                 error "swap of file with different owner should fail"
17906         /bin/true # to clear error code
17907 }
17908 run_test 184b "Forbidden layout swap (will generate errors)"
17909
17910 test_184c() {
17911         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17912         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17913         check_swap_layouts_support
17914         check_swap_layout_no_dom $DIR
17915
17916         local dir0=$DIR/$tdir/$testnum
17917         mkdir -p $dir0 || error "creating dir $dir0"
17918
17919         local ref1=$dir0/ref1
17920         local ref2=$dir0/ref2
17921         local file1=$dir0/file1
17922         local file2=$dir0/file2
17923         # create a file large enough for the concurrent test
17924         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17925         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17926         echo "ref file size: ref1($(stat -c %s $ref1))," \
17927              "ref2($(stat -c %s $ref2))"
17928
17929         cp $ref2 $file2
17930         dd if=$ref1 of=$file1 bs=16k &
17931         local DD_PID=$!
17932
17933         # Make sure dd starts to copy file, but wait at most 5 seconds
17934         local loops=0
17935         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17936
17937         $LFS swap_layouts $file1 $file2
17938         local rc=$?
17939         wait $DD_PID
17940         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17941         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17942
17943         # how many bytes copied before swapping layout
17944         local copied=$(stat -c %s $file2)
17945         local remaining=$(stat -c %s $ref1)
17946         remaining=$((remaining - copied))
17947         echo "Copied $copied bytes before swapping layout..."
17948
17949         cmp -n $copied $file1 $ref2 | grep differ &&
17950                 error "Content mismatch [0, $copied) of ref2 and file1"
17951         cmp -n $copied $file2 $ref1 ||
17952                 error "Content mismatch [0, $copied) of ref1 and file2"
17953         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17954                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17955
17956         # clean up
17957         rm -f $ref1 $ref2 $file1 $file2
17958 }
17959 run_test 184c "Concurrent write and layout swap"
17960
17961 test_184d() {
17962         check_swap_layouts_support
17963         check_swap_layout_no_dom $DIR
17964         [ -z "$(which getfattr 2>/dev/null)" ] &&
17965                 skip_env "no getfattr command"
17966
17967         local file1=$DIR/$tdir/$tfile-1
17968         local file2=$DIR/$tdir/$tfile-2
17969         local file3=$DIR/$tdir/$tfile-3
17970         local lovea1
17971         local lovea2
17972
17973         mkdir -p $DIR/$tdir
17974         touch $file1 || error "create $file1 failed"
17975         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17976                 error "create $file2 failed"
17977         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17978                 error "create $file3 failed"
17979         lovea1=$(get_layout_param $file1)
17980
17981         $LFS swap_layouts $file2 $file3 ||
17982                 error "swap $file2 $file3 layouts failed"
17983         $LFS swap_layouts $file1 $file2 ||
17984                 error "swap $file1 $file2 layouts failed"
17985
17986         lovea2=$(get_layout_param $file2)
17987         echo "$lovea1"
17988         echo "$lovea2"
17989         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17990
17991         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17992         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17993 }
17994 run_test 184d "allow stripeless layouts swap"
17995
17996 test_184e() {
17997         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17998                 skip "Need MDS version at least 2.6.94"
17999         check_swap_layouts_support
18000         check_swap_layout_no_dom $DIR
18001         [ -z "$(which getfattr 2>/dev/null)" ] &&
18002                 skip_env "no getfattr command"
18003
18004         local file1=$DIR/$tdir/$tfile-1
18005         local file2=$DIR/$tdir/$tfile-2
18006         local file3=$DIR/$tdir/$tfile-3
18007         local lovea
18008
18009         mkdir -p $DIR/$tdir
18010         touch $file1 || error "create $file1 failed"
18011         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18012                 error "create $file2 failed"
18013         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18014                 error "create $file3 failed"
18015
18016         $LFS swap_layouts $file1 $file2 ||
18017                 error "swap $file1 $file2 layouts failed"
18018
18019         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18020         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18021
18022         echo 123 > $file1 || error "Should be able to write into $file1"
18023
18024         $LFS swap_layouts $file1 $file3 ||
18025                 error "swap $file1 $file3 layouts failed"
18026
18027         echo 123 > $file1 || error "Should be able to write into $file1"
18028
18029         rm -rf $file1 $file2 $file3
18030 }
18031 run_test 184e "Recreate layout after stripeless layout swaps"
18032
18033 test_184f() {
18034         # Create a file with name longer than sizeof(struct stat) ==
18035         # 144 to see if we can get chars from the file name to appear
18036         # in the returned striping. Note that 'f' == 0x66.
18037         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18038
18039         mkdir -p $DIR/$tdir
18040         mcreate $DIR/$tdir/$file
18041         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18042                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18043         fi
18044 }
18045 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18046
18047 test_185() { # LU-2441
18048         # LU-3553 - no volatile file support in old servers
18049         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18050                 skip "Need MDS version at least 2.3.60"
18051
18052         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18053         touch $DIR/$tdir/spoo
18054         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18055         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18056                 error "cannot create/write a volatile file"
18057         [ "$FILESET" == "" ] &&
18058         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18059                 error "FID is still valid after close"
18060
18061         multiop_bg_pause $DIR/$tdir vVw4096_c
18062         local multi_pid=$!
18063
18064         local OLD_IFS=$IFS
18065         IFS=":"
18066         local fidv=($fid)
18067         IFS=$OLD_IFS
18068         # assume that the next FID for this client is sequential, since stdout
18069         # is unfortunately eaten by multiop_bg_pause
18070         local n=$((${fidv[1]} + 1))
18071         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18072         if [ "$FILESET" == "" ]; then
18073                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18074                         error "FID is missing before close"
18075         fi
18076         kill -USR1 $multi_pid
18077         # 1 second delay, so if mtime change we will see it
18078         sleep 1
18079         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18080         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18081 }
18082 run_test 185 "Volatile file support"
18083
18084 function create_check_volatile() {
18085         local idx=$1
18086         local tgt
18087
18088         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18089         local PID=$!
18090         sleep 1
18091         local FID=$(cat /tmp/${tfile}.fid)
18092         [ "$FID" == "" ] && error "can't get FID for volatile"
18093         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18094         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18095         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18096         kill -USR1 $PID
18097         wait
18098         sleep 1
18099         cancel_lru_locks mdc # flush opencache
18100         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18101         return 0
18102 }
18103
18104 test_185a(){
18105         # LU-12516 - volatile creation via .lustre
18106         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18107                 skip "Need MDS version at least 2.3.55"
18108
18109         create_check_volatile 0
18110         [ $MDSCOUNT -lt 2 ] && return 0
18111
18112         # DNE case
18113         create_check_volatile 1
18114
18115         return 0
18116 }
18117 run_test 185a "Volatile file creation in .lustre/fid/"
18118
18119 test_187a() {
18120         remote_mds_nodsh && skip "remote MDS with nodsh"
18121         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18122                 skip "Need MDS version at least 2.3.0"
18123
18124         local dir0=$DIR/$tdir/$testnum
18125         mkdir -p $dir0 || error "creating dir $dir0"
18126
18127         local file=$dir0/file1
18128         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18129         local dv1=$($LFS data_version $file)
18130         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18131         local dv2=$($LFS data_version $file)
18132         [[ $dv1 != $dv2 ]] ||
18133                 error "data version did not change on write $dv1 == $dv2"
18134
18135         # clean up
18136         rm -f $file1
18137 }
18138 run_test 187a "Test data version change"
18139
18140 test_187b() {
18141         remote_mds_nodsh && skip "remote MDS with nodsh"
18142         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18143                 skip "Need MDS version at least 2.3.0"
18144
18145         local dir0=$DIR/$tdir/$testnum
18146         mkdir -p $dir0 || error "creating dir $dir0"
18147
18148         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18149         [[ ${DV[0]} != ${DV[1]} ]] ||
18150                 error "data version did not change on write"\
18151                       " ${DV[0]} == ${DV[1]}"
18152
18153         # clean up
18154         rm -f $file1
18155 }
18156 run_test 187b "Test data version change on volatile file"
18157
18158 test_200() {
18159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18160         remote_mgs_nodsh && skip "remote MGS with nodsh"
18161         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18162
18163         local POOL=${POOL:-cea1}
18164         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18165         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18166         # Pool OST targets
18167         local first_ost=0
18168         local last_ost=$(($OSTCOUNT - 1))
18169         local ost_step=2
18170         local ost_list=$(seq $first_ost $ost_step $last_ost)
18171         local ost_range="$first_ost $last_ost $ost_step"
18172         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18173         local file_dir=$POOL_ROOT/file_tst
18174         local subdir=$test_path/subdir
18175         local rc=0
18176
18177         while : ; do
18178                 # former test_200a test_200b
18179                 pool_add $POOL                          || { rc=$? ; break; }
18180                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18181                 # former test_200c test_200d
18182                 mkdir -p $test_path
18183                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18184                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18185                 mkdir -p $subdir
18186                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18187                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18188                                                         || { rc=$? ; break; }
18189                 # former test_200e test_200f
18190                 local files=$((OSTCOUNT*3))
18191                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18192                                                         || { rc=$? ; break; }
18193                 pool_create_files $POOL $file_dir $files "$ost_list" \
18194                                                         || { rc=$? ; break; }
18195                 # former test_200g test_200h
18196                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18197                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18198
18199                 # former test_201a test_201b test_201c
18200                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18201
18202                 local f=$test_path/$tfile
18203                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18204                 pool_remove $POOL $f                    || { rc=$? ; break; }
18205                 break
18206         done
18207
18208         destroy_test_pools
18209
18210         return $rc
18211 }
18212 run_test 200 "OST pools"
18213
18214 # usage: default_attr <count | size | offset>
18215 default_attr() {
18216         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18217 }
18218
18219 # usage: check_default_stripe_attr
18220 check_default_stripe_attr() {
18221         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18222         case $1 in
18223         --stripe-count|-c)
18224                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18225         --stripe-size|-S)
18226                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18227         --stripe-index|-i)
18228                 EXPECTED=-1;;
18229         *)
18230                 error "unknown getstripe attr '$1'"
18231         esac
18232
18233         [ $ACTUAL == $EXPECTED ] ||
18234                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18235 }
18236
18237 test_204a() {
18238         test_mkdir $DIR/$tdir
18239         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18240
18241         check_default_stripe_attr --stripe-count
18242         check_default_stripe_attr --stripe-size
18243         check_default_stripe_attr --stripe-index
18244 }
18245 run_test 204a "Print default stripe attributes"
18246
18247 test_204b() {
18248         test_mkdir $DIR/$tdir
18249         $LFS setstripe --stripe-count 1 $DIR/$tdir
18250
18251         check_default_stripe_attr --stripe-size
18252         check_default_stripe_attr --stripe-index
18253 }
18254 run_test 204b "Print default stripe size and offset"
18255
18256 test_204c() {
18257         test_mkdir $DIR/$tdir
18258         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18259
18260         check_default_stripe_attr --stripe-count
18261         check_default_stripe_attr --stripe-index
18262 }
18263 run_test 204c "Print default stripe count and offset"
18264
18265 test_204d() {
18266         test_mkdir $DIR/$tdir
18267         $LFS setstripe --stripe-index 0 $DIR/$tdir
18268
18269         check_default_stripe_attr --stripe-count
18270         check_default_stripe_attr --stripe-size
18271 }
18272 run_test 204d "Print default stripe count and size"
18273
18274 test_204e() {
18275         test_mkdir $DIR/$tdir
18276         $LFS setstripe -d $DIR/$tdir
18277
18278         check_default_stripe_attr --stripe-count --raw
18279         check_default_stripe_attr --stripe-size --raw
18280         check_default_stripe_attr --stripe-index --raw
18281 }
18282 run_test 204e "Print raw stripe attributes"
18283
18284 test_204f() {
18285         test_mkdir $DIR/$tdir
18286         $LFS setstripe --stripe-count 1 $DIR/$tdir
18287
18288         check_default_stripe_attr --stripe-size --raw
18289         check_default_stripe_attr --stripe-index --raw
18290 }
18291 run_test 204f "Print raw stripe size and offset"
18292
18293 test_204g() {
18294         test_mkdir $DIR/$tdir
18295         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18296
18297         check_default_stripe_attr --stripe-count --raw
18298         check_default_stripe_attr --stripe-index --raw
18299 }
18300 run_test 204g "Print raw stripe count and offset"
18301
18302 test_204h() {
18303         test_mkdir $DIR/$tdir
18304         $LFS setstripe --stripe-index 0 $DIR/$tdir
18305
18306         check_default_stripe_attr --stripe-count --raw
18307         check_default_stripe_attr --stripe-size --raw
18308 }
18309 run_test 204h "Print raw stripe count and size"
18310
18311 # Figure out which job scheduler is being used, if any,
18312 # or use a fake one
18313 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18314         JOBENV=SLURM_JOB_ID
18315 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18316         JOBENV=LSB_JOBID
18317 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18318         JOBENV=PBS_JOBID
18319 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18320         JOBENV=LOADL_STEP_ID
18321 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18322         JOBENV=JOB_ID
18323 else
18324         $LCTL list_param jobid_name > /dev/null 2>&1
18325         if [ $? -eq 0 ]; then
18326                 JOBENV=nodelocal
18327         else
18328                 JOBENV=FAKE_JOBID
18329         fi
18330 fi
18331 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18332
18333 verify_jobstats() {
18334         local cmd=($1)
18335         shift
18336         local facets="$@"
18337
18338 # we don't really need to clear the stats for this test to work, since each
18339 # command has a unique jobid, but it makes debugging easier if needed.
18340 #       for facet in $facets; do
18341 #               local dev=$(convert_facet2label $facet)
18342 #               # clear old jobstats
18343 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18344 #       done
18345
18346         # use a new JobID for each test, or we might see an old one
18347         [ "$JOBENV" = "FAKE_JOBID" ] &&
18348                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18349
18350         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18351
18352         [ "$JOBENV" = "nodelocal" ] && {
18353                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18354                 $LCTL set_param jobid_name=$FAKE_JOBID
18355                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18356         }
18357
18358         log "Test: ${cmd[*]}"
18359         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18360
18361         if [ $JOBENV = "FAKE_JOBID" ]; then
18362                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18363         else
18364                 ${cmd[*]}
18365         fi
18366
18367         # all files are created on OST0000
18368         for facet in $facets; do
18369                 local stats="*.$(convert_facet2label $facet).job_stats"
18370
18371                 # strip out libtool wrappers for in-tree executables
18372                 if (( $(do_facet $facet lctl get_param $stats |
18373                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18374                         do_facet $facet lctl get_param $stats
18375                         error "No jobstats for $JOBVAL found on $facet::$stats"
18376                 fi
18377         done
18378 }
18379
18380 jobstats_set() {
18381         local new_jobenv=$1
18382
18383         set_persistent_param_and_check client "jobid_var" \
18384                 "$FSNAME.sys.jobid_var" $new_jobenv
18385 }
18386
18387 test_205a() { # Job stats
18388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18389         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18390                 skip "Need MDS version with at least 2.7.1"
18391         remote_mgs_nodsh && skip "remote MGS with nodsh"
18392         remote_mds_nodsh && skip "remote MDS with nodsh"
18393         remote_ost_nodsh && skip "remote OST with nodsh"
18394         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18395                 skip "Server doesn't support jobstats"
18396         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18397
18398         local old_jobenv=$($LCTL get_param -n jobid_var)
18399         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18400
18401         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18402                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18403         else
18404                 stack_trap "do_facet mgs $PERM_CMD \
18405                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18406         fi
18407         changelog_register
18408
18409         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18410                                 mdt.*.job_cleanup_interval | head -n 1)
18411         local new_interval=5
18412         do_facet $SINGLEMDS \
18413                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18414         stack_trap "do_facet $SINGLEMDS \
18415                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18416         local start=$SECONDS
18417
18418         local cmd
18419         # mkdir
18420         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18421         verify_jobstats "$cmd" "$SINGLEMDS"
18422         # rmdir
18423         cmd="rmdir $DIR/$tdir"
18424         verify_jobstats "$cmd" "$SINGLEMDS"
18425         # mkdir on secondary MDT
18426         if [ $MDSCOUNT -gt 1 ]; then
18427                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18428                 verify_jobstats "$cmd" "mds2"
18429         fi
18430         # mknod
18431         cmd="mknod $DIR/$tfile c 1 3"
18432         verify_jobstats "$cmd" "$SINGLEMDS"
18433         # unlink
18434         cmd="rm -f $DIR/$tfile"
18435         verify_jobstats "$cmd" "$SINGLEMDS"
18436         # create all files on OST0000 so verify_jobstats can find OST stats
18437         # open & close
18438         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18439         verify_jobstats "$cmd" "$SINGLEMDS"
18440         # setattr
18441         cmd="touch $DIR/$tfile"
18442         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18443         # write
18444         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18445         verify_jobstats "$cmd" "ost1"
18446         # read
18447         cancel_lru_locks osc
18448         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18449         verify_jobstats "$cmd" "ost1"
18450         # truncate
18451         cmd="$TRUNCATE $DIR/$tfile 0"
18452         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18453         # rename
18454         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18455         verify_jobstats "$cmd" "$SINGLEMDS"
18456         # jobstats expiry - sleep until old stats should be expired
18457         local left=$((new_interval + 5 - (SECONDS - start)))
18458         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18459                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18460                         "0" $left
18461         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18462         verify_jobstats "$cmd" "$SINGLEMDS"
18463         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18464             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18465
18466         # Ensure that jobid are present in changelog (if supported by MDS)
18467         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18468                 changelog_dump | tail -10
18469                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18470                 [ $jobids -eq 9 ] ||
18471                         error "Wrong changelog jobid count $jobids != 9"
18472
18473                 # LU-5862
18474                 JOBENV="disable"
18475                 jobstats_set $JOBENV
18476                 touch $DIR/$tfile
18477                 changelog_dump | grep $tfile
18478                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18479                 [ $jobids -eq 0 ] ||
18480                         error "Unexpected jobids when jobid_var=$JOBENV"
18481         fi
18482
18483         # test '%j' access to environment variable - if supported
18484         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18485                 JOBENV="JOBCOMPLEX"
18486                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18487
18488                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18489         fi
18490
18491         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18492                 JOBENV="JOBCOMPLEX"
18493                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18494
18495                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18496         fi
18497
18498         # test '%j' access to per-session jobid - if supported
18499         if lctl list_param jobid_this_session > /dev/null 2>&1
18500         then
18501                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18502                 lctl set_param jobid_this_session=$USER
18503
18504                 JOBENV="JOBCOMPLEX"
18505                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18506
18507                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18508         fi
18509 }
18510 run_test 205a "Verify job stats"
18511
18512 # LU-13117, LU-13597
18513 test_205b() {
18514         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18515                 skip "Need MDS version at least 2.13.54.91"
18516
18517         job_stats="mdt.*.job_stats"
18518         $LCTL set_param $job_stats=clear
18519         # Setting jobid_var to USER might not be supported
18520         $LCTL set_param jobid_var=USER || true
18521         $LCTL set_param jobid_name="%e.%u"
18522         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18523         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18524                 grep "job_id:.*foolish" &&
18525                         error "Unexpected jobid found"
18526         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18527                 grep "open:.*min.*max.*sum" ||
18528                         error "wrong job_stats format found"
18529 }
18530 run_test 205b "Verify job stats jobid and output format"
18531
18532 # LU-13733
18533 test_205c() {
18534         $LCTL set_param llite.*.stats=0
18535         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18536         $LCTL get_param llite.*.stats
18537         $LCTL get_param llite.*.stats | grep \
18538                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18539                         error "wrong client stats format found"
18540 }
18541 run_test 205c "Verify client stats format"
18542
18543 # LU-1480, LU-1773 and LU-1657
18544 test_206() {
18545         mkdir -p $DIR/$tdir
18546         $LFS setstripe -c -1 $DIR/$tdir
18547 #define OBD_FAIL_LOV_INIT 0x1403
18548         $LCTL set_param fail_loc=0xa0001403
18549         $LCTL set_param fail_val=1
18550         touch $DIR/$tdir/$tfile || true
18551 }
18552 run_test 206 "fail lov_init_raid0() doesn't lbug"
18553
18554 test_207a() {
18555         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18556         local fsz=`stat -c %s $DIR/$tfile`
18557         cancel_lru_locks mdc
18558
18559         # do not return layout in getattr intent
18560 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18561         $LCTL set_param fail_loc=0x170
18562         local sz=`stat -c %s $DIR/$tfile`
18563
18564         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18565
18566         rm -rf $DIR/$tfile
18567 }
18568 run_test 207a "can refresh layout at glimpse"
18569
18570 test_207b() {
18571         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18572         local cksum=`md5sum $DIR/$tfile`
18573         local fsz=`stat -c %s $DIR/$tfile`
18574         cancel_lru_locks mdc
18575         cancel_lru_locks osc
18576
18577         # do not return layout in getattr intent
18578 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18579         $LCTL set_param fail_loc=0x171
18580
18581         # it will refresh layout after the file is opened but before read issues
18582         echo checksum is "$cksum"
18583         echo "$cksum" |md5sum -c --quiet || error "file differs"
18584
18585         rm -rf $DIR/$tfile
18586 }
18587 run_test 207b "can refresh layout at open"
18588
18589 test_208() {
18590         # FIXME: in this test suite, only RD lease is used. This is okay
18591         # for now as only exclusive open is supported. After generic lease
18592         # is done, this test suite should be revised. - Jinshan
18593
18594         remote_mds_nodsh && skip "remote MDS with nodsh"
18595         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18596                 skip "Need MDS version at least 2.4.52"
18597
18598         echo "==== test 1: verify get lease work"
18599         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18600
18601         echo "==== test 2: verify lease can be broken by upcoming open"
18602         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18603         local PID=$!
18604         sleep 2
18605
18606         $MULTIOP $DIR/$tfile oO_RDWR:c
18607         kill -USR1 $PID && wait $PID || error "break lease error"
18608
18609         echo "==== test 3: verify lease can't be granted if an open already exists"
18610         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18611         local PID=$!
18612         sleep 2
18613
18614         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18615         kill -USR1 $PID && wait $PID || error "open file error"
18616
18617         echo "==== test 4: lease can sustain over recovery"
18618         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18619         PID=$!
18620         sleep 2
18621
18622         fail mds1
18623
18624         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18625
18626         echo "==== test 5: lease broken can't be regained by replay"
18627         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18628         PID=$!
18629         sleep 2
18630
18631         # open file to break lease and then recovery
18632         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18633         fail mds1
18634
18635         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18636
18637         rm -f $DIR/$tfile
18638 }
18639 run_test 208 "Exclusive open"
18640
18641 test_209() {
18642         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18643                 skip_env "must have disp_stripe"
18644
18645         touch $DIR/$tfile
18646         sync; sleep 5; sync;
18647
18648         echo 3 > /proc/sys/vm/drop_caches
18649         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18650                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18651         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18652
18653         # open/close 500 times
18654         for i in $(seq 500); do
18655                 cat $DIR/$tfile
18656         done
18657
18658         echo 3 > /proc/sys/vm/drop_caches
18659         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18660                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18661         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18662
18663         echo "before: $req_before, after: $req_after"
18664         [ $((req_after - req_before)) -ge 300 ] &&
18665                 error "open/close requests are not freed"
18666         return 0
18667 }
18668 run_test 209 "read-only open/close requests should be freed promptly"
18669
18670 test_210() {
18671         local pid
18672
18673         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18674         pid=$!
18675         sleep 1
18676
18677         $LFS getstripe $DIR/$tfile
18678         kill -USR1 $pid
18679         wait $pid || error "multiop failed"
18680
18681         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18682         pid=$!
18683         sleep 1
18684
18685         $LFS getstripe $DIR/$tfile
18686         kill -USR1 $pid
18687         wait $pid || error "multiop failed"
18688 }
18689 run_test 210 "lfs getstripe does not break leases"
18690
18691 test_212() {
18692         size=`date +%s`
18693         size=$((size % 8192 + 1))
18694         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18695         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18696         rm -f $DIR/f212 $DIR/f212.xyz
18697 }
18698 run_test 212 "Sendfile test ============================================"
18699
18700 test_213() {
18701         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18702         cancel_lru_locks osc
18703         lctl set_param fail_loc=0x8000040f
18704         # generate a read lock
18705         cat $DIR/$tfile > /dev/null
18706         # write to the file, it will try to cancel the above read lock.
18707         cat /etc/hosts >> $DIR/$tfile
18708 }
18709 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18710
18711 test_214() { # for bug 20133
18712         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18713         for (( i=0; i < 340; i++ )) ; do
18714                 touch $DIR/$tdir/d214c/a$i
18715         done
18716
18717         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18718         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18719         ls $DIR/d214c || error "ls $DIR/d214c failed"
18720         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18721         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18722 }
18723 run_test 214 "hash-indexed directory test - bug 20133"
18724
18725 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18726 create_lnet_proc_files() {
18727         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18728 }
18729
18730 # counterpart of create_lnet_proc_files
18731 remove_lnet_proc_files() {
18732         rm -f $TMP/lnet_$1.sys
18733 }
18734
18735 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18736 # 3rd arg as regexp for body
18737 check_lnet_proc_stats() {
18738         local l=$(cat "$TMP/lnet_$1" |wc -l)
18739         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18740
18741         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18742 }
18743
18744 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18745 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18746 # optional and can be regexp for 2nd line (lnet.routes case)
18747 check_lnet_proc_entry() {
18748         local blp=2          # blp stands for 'position of 1st line of body'
18749         [ -z "$5" ] || blp=3 # lnet.routes case
18750
18751         local l=$(cat "$TMP/lnet_$1" |wc -l)
18752         # subtracting one from $blp because the body can be empty
18753         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18754
18755         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18756                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18757
18758         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18759                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18760
18761         # bail out if any unexpected line happened
18762         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18763         [ "$?" != 0 ] || error "$2 misformatted"
18764 }
18765
18766 test_215() { # for bugs 18102, 21079, 21517
18767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18768
18769         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18770         local P='[1-9][0-9]*'           # positive numeric
18771         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18772         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18773         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18774         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18775
18776         local L1 # regexp for 1st line
18777         local L2 # regexp for 2nd line (optional)
18778         local BR # regexp for the rest (body)
18779
18780         # lnet.stats should look as 11 space-separated non-negative numerics
18781         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18782         create_lnet_proc_files "stats"
18783         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18784         remove_lnet_proc_files "stats"
18785
18786         # lnet.routes should look like this:
18787         # Routing disabled/enabled
18788         # net hops priority state router
18789         # where net is a string like tcp0, hops > 0, priority >= 0,
18790         # state is up/down,
18791         # router is a string like 192.168.1.1@tcp2
18792         L1="^Routing (disabled|enabled)$"
18793         L2="^net +hops +priority +state +router$"
18794         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18795         create_lnet_proc_files "routes"
18796         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18797         remove_lnet_proc_files "routes"
18798
18799         # lnet.routers should look like this:
18800         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18801         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18802         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18803         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18804         L1="^ref +rtr_ref +alive +router$"
18805         BR="^$P +$P +(up|down) +$NID$"
18806         create_lnet_proc_files "routers"
18807         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18808         remove_lnet_proc_files "routers"
18809
18810         # lnet.peers should look like this:
18811         # nid refs state last max rtr min tx min queue
18812         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18813         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18814         # numeric (0 or >0 or <0), queue >= 0.
18815         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18816         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18817         create_lnet_proc_files "peers"
18818         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18819         remove_lnet_proc_files "peers"
18820
18821         # lnet.buffers  should look like this:
18822         # pages count credits min
18823         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18824         L1="^pages +count +credits +min$"
18825         BR="^ +$N +$N +$I +$I$"
18826         create_lnet_proc_files "buffers"
18827         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18828         remove_lnet_proc_files "buffers"
18829
18830         # lnet.nis should look like this:
18831         # nid status alive refs peer rtr max tx min
18832         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18833         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18834         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18835         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18836         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18837         create_lnet_proc_files "nis"
18838         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18839         remove_lnet_proc_files "nis"
18840
18841         # can we successfully write to lnet.stats?
18842         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18843 }
18844 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18845
18846 test_216() { # bug 20317
18847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18848         remote_ost_nodsh && skip "remote OST with nodsh"
18849
18850         local node
18851         local facets=$(get_facets OST)
18852         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18853
18854         save_lustre_params client "osc.*.contention_seconds" > $p
18855         save_lustre_params $facets \
18856                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18857         save_lustre_params $facets \
18858                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18859         save_lustre_params $facets \
18860                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18861         clear_stats osc.*.osc_stats
18862
18863         # agressive lockless i/o settings
18864         do_nodes $(comma_list $(osts_nodes)) \
18865                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18866                         ldlm.namespaces.filter-*.contended_locks=0 \
18867                         ldlm.namespaces.filter-*.contention_seconds=60"
18868         lctl set_param -n osc.*.contention_seconds=60
18869
18870         $DIRECTIO write $DIR/$tfile 0 10 4096
18871         $CHECKSTAT -s 40960 $DIR/$tfile
18872
18873         # disable lockless i/o
18874         do_nodes $(comma_list $(osts_nodes)) \
18875                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18876                         ldlm.namespaces.filter-*.contended_locks=32 \
18877                         ldlm.namespaces.filter-*.contention_seconds=0"
18878         lctl set_param -n osc.*.contention_seconds=0
18879         clear_stats osc.*.osc_stats
18880
18881         dd if=/dev/zero of=$DIR/$tfile count=0
18882         $CHECKSTAT -s 0 $DIR/$tfile
18883
18884         restore_lustre_params <$p
18885         rm -f $p
18886         rm $DIR/$tfile
18887 }
18888 run_test 216 "check lockless direct write updates file size and kms correctly"
18889
18890 test_217() { # bug 22430
18891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18892
18893         local node
18894         local nid
18895
18896         for node in $(nodes_list); do
18897                 nid=$(host_nids_address $node $NETTYPE)
18898                 if [[ $nid = *-* ]] ; then
18899                         echo "lctl ping $(h2nettype $nid)"
18900                         lctl ping $(h2nettype $nid)
18901                 else
18902                         echo "skipping $node (no hyphen detected)"
18903                 fi
18904         done
18905 }
18906 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18907
18908 test_218() {
18909        # do directio so as not to populate the page cache
18910        log "creating a 10 Mb file"
18911        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18912        log "starting reads"
18913        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18914        log "truncating the file"
18915        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18916        log "killing dd"
18917        kill %+ || true # reads might have finished
18918        echo "wait until dd is finished"
18919        wait
18920        log "removing the temporary file"
18921        rm -rf $DIR/$tfile || error "tmp file removal failed"
18922 }
18923 run_test 218 "parallel read and truncate should not deadlock"
18924
18925 test_219() {
18926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18927
18928         # write one partial page
18929         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18930         # set no grant so vvp_io_commit_write will do sync write
18931         $LCTL set_param fail_loc=0x411
18932         # write a full page at the end of file
18933         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18934
18935         $LCTL set_param fail_loc=0
18936         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18937         $LCTL set_param fail_loc=0x411
18938         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18939
18940         # LU-4201
18941         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18942         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18943 }
18944 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18945
18946 test_220() { #LU-325
18947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18948         remote_ost_nodsh && skip "remote OST with nodsh"
18949         remote_mds_nodsh && skip "remote MDS with nodsh"
18950         remote_mgs_nodsh && skip "remote MGS with nodsh"
18951
18952         local OSTIDX=0
18953
18954         # create on MDT0000 so the last_id and next_id are correct
18955         mkdir_on_mdt0 $DIR/$tdir
18956         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18957         OST=${OST%_UUID}
18958
18959         # on the mdt's osc
18960         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18961         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18962                         osp.$mdtosc_proc1.prealloc_last_id)
18963         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18964                         osp.$mdtosc_proc1.prealloc_next_id)
18965
18966         $LFS df -i
18967
18968         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18969         #define OBD_FAIL_OST_ENOINO              0x229
18970         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18971         create_pool $FSNAME.$TESTNAME || return 1
18972         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18973
18974         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18975
18976         MDSOBJS=$((last_id - next_id))
18977         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18978
18979         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18980         echo "OST still has $count kbytes free"
18981
18982         echo "create $MDSOBJS files @next_id..."
18983         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18984
18985         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18986                         osp.$mdtosc_proc1.prealloc_last_id)
18987         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18988                         osp.$mdtosc_proc1.prealloc_next_id)
18989
18990         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18991         $LFS df -i
18992
18993         echo "cleanup..."
18994
18995         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18996         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18997
18998         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18999                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19000         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19001                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19002         echo "unlink $MDSOBJS files @$next_id..."
19003         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19004 }
19005 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19006
19007 test_221() {
19008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19009
19010         dd if=`which date` of=$MOUNT/date oflag=sync
19011         chmod +x $MOUNT/date
19012
19013         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19014         $LCTL set_param fail_loc=0x80001401
19015
19016         $MOUNT/date > /dev/null
19017         rm -f $MOUNT/date
19018 }
19019 run_test 221 "make sure fault and truncate race to not cause OOM"
19020
19021 test_222a () {
19022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19023
19024         rm -rf $DIR/$tdir
19025         test_mkdir $DIR/$tdir
19026         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19027         createmany -o $DIR/$tdir/$tfile 10
19028         cancel_lru_locks mdc
19029         cancel_lru_locks osc
19030         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19031         $LCTL set_param fail_loc=0x31a
19032         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19033         $LCTL set_param fail_loc=0
19034         rm -r $DIR/$tdir
19035 }
19036 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19037
19038 test_222b () {
19039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19040
19041         rm -rf $DIR/$tdir
19042         test_mkdir $DIR/$tdir
19043         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19044         createmany -o $DIR/$tdir/$tfile 10
19045         cancel_lru_locks mdc
19046         cancel_lru_locks osc
19047         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19048         $LCTL set_param fail_loc=0x31a
19049         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19050         $LCTL set_param fail_loc=0
19051 }
19052 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19053
19054 test_223 () {
19055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19056
19057         rm -rf $DIR/$tdir
19058         test_mkdir $DIR/$tdir
19059         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19060         createmany -o $DIR/$tdir/$tfile 10
19061         cancel_lru_locks mdc
19062         cancel_lru_locks osc
19063         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19064         $LCTL set_param fail_loc=0x31b
19065         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19066         $LCTL set_param fail_loc=0
19067         rm -r $DIR/$tdir
19068 }
19069 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19070
19071 test_224a() { # LU-1039, MRP-303
19072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19073         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19074         $LCTL set_param fail_loc=0x508
19075         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19076         $LCTL set_param fail_loc=0
19077         df $DIR
19078 }
19079 run_test 224a "Don't panic on bulk IO failure"
19080
19081 test_224bd_sub() { # LU-1039, MRP-303
19082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19083         local timeout=$1
19084
19085         shift
19086         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19087
19088         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19089
19090         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19091         cancel_lru_locks osc
19092         set_checksums 0
19093         stack_trap "set_checksums $ORIG_CSUM" EXIT
19094         local at_max_saved=0
19095
19096         # adaptive timeouts may prevent seeing the issue
19097         if at_is_enabled; then
19098                 at_max_saved=$(at_max_get mds)
19099                 at_max_set 0 mds client
19100                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19101         fi
19102
19103         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19104         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19105         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19106
19107         do_facet ost1 $LCTL set_param fail_loc=0
19108         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19109         df $DIR
19110 }
19111
19112 test_224b() {
19113         test_224bd_sub 3 error "dd failed"
19114 }
19115 run_test 224b "Don't panic on bulk IO failure"
19116
19117 test_224c() { # LU-6441
19118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19119         remote_mds_nodsh && skip "remote MDS with nodsh"
19120
19121         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19122         save_writethrough $p
19123         set_cache writethrough on
19124
19125         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19126         local at_max=$($LCTL get_param -n at_max)
19127         local timeout=$($LCTL get_param -n timeout)
19128         local test_at="at_max"
19129         local param_at="$FSNAME.sys.at_max"
19130         local test_timeout="timeout"
19131         local param_timeout="$FSNAME.sys.timeout"
19132
19133         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19134
19135         set_persistent_param_and_check client "$test_at" "$param_at" 0
19136         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19137
19138         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19139         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19140         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19141         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19142         sync
19143         do_facet ost1 "$LCTL set_param fail_loc=0"
19144
19145         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19146         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19147                 $timeout
19148
19149         $LCTL set_param -n $pages_per_rpc
19150         restore_lustre_params < $p
19151         rm -f $p
19152 }
19153 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19154
19155 test_224d() { # LU-11169
19156         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19157 }
19158 run_test 224d "Don't corrupt data on bulk IO timeout"
19159
19160 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19161 test_225a () {
19162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19163         if [ -z ${MDSSURVEY} ]; then
19164                 skip_env "mds-survey not found"
19165         fi
19166         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19167                 skip "Need MDS version at least 2.2.51"
19168
19169         local mds=$(facet_host $SINGLEMDS)
19170         local target=$(do_nodes $mds 'lctl dl' |
19171                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19172
19173         local cmd1="file_count=1000 thrhi=4"
19174         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19175         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19176         local cmd="$cmd1 $cmd2 $cmd3"
19177
19178         rm -f ${TMP}/mds_survey*
19179         echo + $cmd
19180         eval $cmd || error "mds-survey with zero-stripe failed"
19181         cat ${TMP}/mds_survey*
19182         rm -f ${TMP}/mds_survey*
19183 }
19184 run_test 225a "Metadata survey sanity with zero-stripe"
19185
19186 test_225b () {
19187         if [ -z ${MDSSURVEY} ]; then
19188                 skip_env "mds-survey not found"
19189         fi
19190         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19191                 skip "Need MDS version at least 2.2.51"
19192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19193         remote_mds_nodsh && skip "remote MDS with nodsh"
19194         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19195                 skip_env "Need to mount OST to test"
19196         fi
19197
19198         local mds=$(facet_host $SINGLEMDS)
19199         local target=$(do_nodes $mds 'lctl dl' |
19200                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19201
19202         local cmd1="file_count=1000 thrhi=4"
19203         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19204         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19205         local cmd="$cmd1 $cmd2 $cmd3"
19206
19207         rm -f ${TMP}/mds_survey*
19208         echo + $cmd
19209         eval $cmd || error "mds-survey with stripe_count failed"
19210         cat ${TMP}/mds_survey*
19211         rm -f ${TMP}/mds_survey*
19212 }
19213 run_test 225b "Metadata survey sanity with stripe_count = 1"
19214
19215 mcreate_path2fid () {
19216         local mode=$1
19217         local major=$2
19218         local minor=$3
19219         local name=$4
19220         local desc=$5
19221         local path=$DIR/$tdir/$name
19222         local fid
19223         local rc
19224         local fid_path
19225
19226         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19227                 error "cannot create $desc"
19228
19229         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19230         rc=$?
19231         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19232
19233         fid_path=$($LFS fid2path $MOUNT $fid)
19234         rc=$?
19235         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19236
19237         [ "$path" == "$fid_path" ] ||
19238                 error "fid2path returned $fid_path, expected $path"
19239
19240         echo "pass with $path and $fid"
19241 }
19242
19243 test_226a () {
19244         rm -rf $DIR/$tdir
19245         mkdir -p $DIR/$tdir
19246
19247         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19248         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19249         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19250         mcreate_path2fid 0040666 0 0 dir "directory"
19251         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19252         mcreate_path2fid 0100666 0 0 file "regular file"
19253         mcreate_path2fid 0120666 0 0 link "symbolic link"
19254         mcreate_path2fid 0140666 0 0 sock "socket"
19255 }
19256 run_test 226a "call path2fid and fid2path on files of all type"
19257
19258 test_226b () {
19259         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19260
19261         local MDTIDX=1
19262
19263         rm -rf $DIR/$tdir
19264         mkdir -p $DIR/$tdir
19265         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19266                 error "create remote directory failed"
19267         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19268         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19269                                 "character special file (null)"
19270         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19271                                 "character special file (no device)"
19272         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19273         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19274                                 "block special file (loop)"
19275         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19276         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19277         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19278 }
19279 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19280
19281 test_226c () {
19282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19283         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19284                 skip "Need MDS version at least 2.13.55"
19285
19286         local submnt=/mnt/submnt
19287         local srcfile=/etc/passwd
19288         local dstfile=$submnt/passwd
19289         local path
19290         local fid
19291
19292         rm -rf $DIR/$tdir
19293         rm -rf $submnt
19294         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19295                 error "create remote directory failed"
19296         mkdir -p $submnt || error "create $submnt failed"
19297         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19298                 error "mount $submnt failed"
19299         stack_trap "umount $submnt" EXIT
19300
19301         cp $srcfile $dstfile
19302         fid=$($LFS path2fid $dstfile)
19303         path=$($LFS fid2path $submnt "$fid")
19304         [ "$path" = "$dstfile" ] ||
19305                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19306 }
19307 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19308
19309 # LU-1299 Executing or running ldd on a truncated executable does not
19310 # cause an out-of-memory condition.
19311 test_227() {
19312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19313         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19314
19315         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19316         chmod +x $MOUNT/date
19317
19318         $MOUNT/date > /dev/null
19319         ldd $MOUNT/date > /dev/null
19320         rm -f $MOUNT/date
19321 }
19322 run_test 227 "running truncated executable does not cause OOM"
19323
19324 # LU-1512 try to reuse idle OI blocks
19325 test_228a() {
19326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19327         remote_mds_nodsh && skip "remote MDS with nodsh"
19328         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19329
19330         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19331         local myDIR=$DIR/$tdir
19332
19333         mkdir -p $myDIR
19334         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19335         $LCTL set_param fail_loc=0x80001002
19336         createmany -o $myDIR/t- 10000
19337         $LCTL set_param fail_loc=0
19338         # The guard is current the largest FID holder
19339         touch $myDIR/guard
19340         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19341                     tr -d '[')
19342         local IDX=$(($SEQ % 64))
19343
19344         do_facet $SINGLEMDS sync
19345         # Make sure journal flushed.
19346         sleep 6
19347         local blk1=$(do_facet $SINGLEMDS \
19348                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19349                      grep Blockcount | awk '{print $4}')
19350
19351         # Remove old files, some OI blocks will become idle.
19352         unlinkmany $myDIR/t- 10000
19353         # Create new files, idle OI blocks should be reused.
19354         createmany -o $myDIR/t- 2000
19355         do_facet $SINGLEMDS sync
19356         # Make sure journal flushed.
19357         sleep 6
19358         local blk2=$(do_facet $SINGLEMDS \
19359                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19360                      grep Blockcount | awk '{print $4}')
19361
19362         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19363 }
19364 run_test 228a "try to reuse idle OI blocks"
19365
19366 test_228b() {
19367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19368         remote_mds_nodsh && skip "remote MDS with nodsh"
19369         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19370
19371         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19372         local myDIR=$DIR/$tdir
19373
19374         mkdir -p $myDIR
19375         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19376         $LCTL set_param fail_loc=0x80001002
19377         createmany -o $myDIR/t- 10000
19378         $LCTL set_param fail_loc=0
19379         # The guard is current the largest FID holder
19380         touch $myDIR/guard
19381         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19382                     tr -d '[')
19383         local IDX=$(($SEQ % 64))
19384
19385         do_facet $SINGLEMDS sync
19386         # Make sure journal flushed.
19387         sleep 6
19388         local blk1=$(do_facet $SINGLEMDS \
19389                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19390                      grep Blockcount | awk '{print $4}')
19391
19392         # Remove old files, some OI blocks will become idle.
19393         unlinkmany $myDIR/t- 10000
19394
19395         # stop the MDT
19396         stop $SINGLEMDS || error "Fail to stop MDT."
19397         # remount the MDT
19398         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19399
19400         df $MOUNT || error "Fail to df."
19401         # Create new files, idle OI blocks should be reused.
19402         createmany -o $myDIR/t- 2000
19403         do_facet $SINGLEMDS sync
19404         # Make sure journal flushed.
19405         sleep 6
19406         local blk2=$(do_facet $SINGLEMDS \
19407                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19408                      grep Blockcount | awk '{print $4}')
19409
19410         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19411 }
19412 run_test 228b "idle OI blocks can be reused after MDT restart"
19413
19414 #LU-1881
19415 test_228c() {
19416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19417         remote_mds_nodsh && skip "remote MDS with nodsh"
19418         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19419
19420         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19421         local myDIR=$DIR/$tdir
19422
19423         mkdir -p $myDIR
19424         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19425         $LCTL set_param fail_loc=0x80001002
19426         # 20000 files can guarantee there are index nodes in the OI file
19427         createmany -o $myDIR/t- 20000
19428         $LCTL set_param fail_loc=0
19429         # The guard is current the largest FID holder
19430         touch $myDIR/guard
19431         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19432                     tr -d '[')
19433         local IDX=$(($SEQ % 64))
19434
19435         do_facet $SINGLEMDS sync
19436         # Make sure journal flushed.
19437         sleep 6
19438         local blk1=$(do_facet $SINGLEMDS \
19439                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19440                      grep Blockcount | awk '{print $4}')
19441
19442         # Remove old files, some OI blocks will become idle.
19443         unlinkmany $myDIR/t- 20000
19444         rm -f $myDIR/guard
19445         # The OI file should become empty now
19446
19447         # Create new files, idle OI blocks should be reused.
19448         createmany -o $myDIR/t- 2000
19449         do_facet $SINGLEMDS sync
19450         # Make sure journal flushed.
19451         sleep 6
19452         local blk2=$(do_facet $SINGLEMDS \
19453                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19454                      grep Blockcount | awk '{print $4}')
19455
19456         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19457 }
19458 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19459
19460 test_229() { # LU-2482, LU-3448
19461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19462         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19463         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19464                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19465
19466         rm -f $DIR/$tfile
19467
19468         # Create a file with a released layout and stripe count 2.
19469         $MULTIOP $DIR/$tfile H2c ||
19470                 error "failed to create file with released layout"
19471
19472         $LFS getstripe -v $DIR/$tfile
19473
19474         local pattern=$($LFS getstripe -L $DIR/$tfile)
19475         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19476
19477         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19478                 error "getstripe"
19479         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19480         stat $DIR/$tfile || error "failed to stat released file"
19481
19482         chown $RUNAS_ID $DIR/$tfile ||
19483                 error "chown $RUNAS_ID $DIR/$tfile failed"
19484
19485         chgrp $RUNAS_ID $DIR/$tfile ||
19486                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19487
19488         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19489         rm $DIR/$tfile || error "failed to remove released file"
19490 }
19491 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19492
19493 test_230a() {
19494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19496         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19497                 skip "Need MDS version at least 2.11.52"
19498
19499         local MDTIDX=1
19500
19501         test_mkdir $DIR/$tdir
19502         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19503         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19504         [ $mdt_idx -ne 0 ] &&
19505                 error "create local directory on wrong MDT $mdt_idx"
19506
19507         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19508                         error "create remote directory failed"
19509         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19510         [ $mdt_idx -ne $MDTIDX ] &&
19511                 error "create remote directory on wrong MDT $mdt_idx"
19512
19513         createmany -o $DIR/$tdir/test_230/t- 10 ||
19514                 error "create files on remote directory failed"
19515         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19516         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19517         rm -r $DIR/$tdir || error "unlink remote directory failed"
19518 }
19519 run_test 230a "Create remote directory and files under the remote directory"
19520
19521 test_230b() {
19522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19524         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19525                 skip "Need MDS version at least 2.11.52"
19526
19527         local MDTIDX=1
19528         local mdt_index
19529         local i
19530         local file
19531         local pid
19532         local stripe_count
19533         local migrate_dir=$DIR/$tdir/migrate_dir
19534         local other_dir=$DIR/$tdir/other_dir
19535
19536         test_mkdir $DIR/$tdir
19537         test_mkdir -i0 -c1 $migrate_dir
19538         test_mkdir -i0 -c1 $other_dir
19539         for ((i=0; i<10; i++)); do
19540                 mkdir -p $migrate_dir/dir_${i}
19541                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19542                         error "create files under remote dir failed $i"
19543         done
19544
19545         cp /etc/passwd $migrate_dir/$tfile
19546         cp /etc/passwd $other_dir/$tfile
19547         chattr +SAD $migrate_dir
19548         chattr +SAD $migrate_dir/$tfile
19549
19550         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19551         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19552         local old_dir_mode=$(stat -c%f $migrate_dir)
19553         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19554
19555         mkdir -p $migrate_dir/dir_default_stripe2
19556         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19557         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19558
19559         mkdir -p $other_dir
19560         ln $migrate_dir/$tfile $other_dir/luna
19561         ln $migrate_dir/$tfile $migrate_dir/sofia
19562         ln $other_dir/$tfile $migrate_dir/david
19563         ln -s $migrate_dir/$tfile $other_dir/zachary
19564         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19565         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19566
19567         local len
19568         local lnktgt
19569
19570         # inline symlink
19571         for len in 58 59 60; do
19572                 lnktgt=$(str_repeat 'l' $len)
19573                 touch $migrate_dir/$lnktgt
19574                 ln -s $lnktgt $migrate_dir/${len}char_ln
19575         done
19576
19577         # PATH_MAX
19578         for len in 4094 4095; do
19579                 lnktgt=$(str_repeat 'l' $len)
19580                 ln -s $lnktgt $migrate_dir/${len}char_ln
19581         done
19582
19583         # NAME_MAX
19584         for len in 254 255; do
19585                 touch $migrate_dir/$(str_repeat 'l' $len)
19586         done
19587
19588         $LFS migrate -m $MDTIDX $migrate_dir ||
19589                 error "fails on migrating remote dir to MDT1"
19590
19591         echo "migratate to MDT1, then checking.."
19592         for ((i = 0; i < 10; i++)); do
19593                 for file in $(find $migrate_dir/dir_${i}); do
19594                         mdt_index=$($LFS getstripe -m $file)
19595                         # broken symlink getstripe will fail
19596                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19597                                 error "$file is not on MDT${MDTIDX}"
19598                 done
19599         done
19600
19601         # the multiple link file should still in MDT0
19602         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19603         [ $mdt_index == 0 ] ||
19604                 error "$file is not on MDT${MDTIDX}"
19605
19606         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19607         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19608                 error " expect $old_dir_flag get $new_dir_flag"
19609
19610         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19611         [ "$old_file_flag" = "$new_file_flag" ] ||
19612                 error " expect $old_file_flag get $new_file_flag"
19613
19614         local new_dir_mode=$(stat -c%f $migrate_dir)
19615         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19616                 error "expect mode $old_dir_mode get $new_dir_mode"
19617
19618         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19619         [ "$old_file_mode" = "$new_file_mode" ] ||
19620                 error "expect mode $old_file_mode get $new_file_mode"
19621
19622         diff /etc/passwd $migrate_dir/$tfile ||
19623                 error "$tfile different after migration"
19624
19625         diff /etc/passwd $other_dir/luna ||
19626                 error "luna different after migration"
19627
19628         diff /etc/passwd $migrate_dir/sofia ||
19629                 error "sofia different after migration"
19630
19631         diff /etc/passwd $migrate_dir/david ||
19632                 error "david different after migration"
19633
19634         diff /etc/passwd $other_dir/zachary ||
19635                 error "zachary different after migration"
19636
19637         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19638                 error "${tfile}_ln different after migration"
19639
19640         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19641                 error "${tfile}_ln_other different after migration"
19642
19643         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19644         [ $stripe_count = 2 ] ||
19645                 error "dir strpe_count $d != 2 after migration."
19646
19647         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19648         [ $stripe_count = 2 ] ||
19649                 error "file strpe_count $d != 2 after migration."
19650
19651         #migrate back to MDT0
19652         MDTIDX=0
19653
19654         $LFS migrate -m $MDTIDX $migrate_dir ||
19655                 error "fails on migrating remote dir to MDT0"
19656
19657         echo "migrate back to MDT0, checking.."
19658         for file in $(find $migrate_dir); do
19659                 mdt_index=$($LFS getstripe -m $file)
19660                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19661                         error "$file is not on MDT${MDTIDX}"
19662         done
19663
19664         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19665         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19666                 error " expect $old_dir_flag get $new_dir_flag"
19667
19668         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19669         [ "$old_file_flag" = "$new_file_flag" ] ||
19670                 error " expect $old_file_flag get $new_file_flag"
19671
19672         local new_dir_mode=$(stat -c%f $migrate_dir)
19673         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19674                 error "expect mode $old_dir_mode get $new_dir_mode"
19675
19676         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19677         [ "$old_file_mode" = "$new_file_mode" ] ||
19678                 error "expect mode $old_file_mode get $new_file_mode"
19679
19680         diff /etc/passwd ${migrate_dir}/$tfile ||
19681                 error "$tfile different after migration"
19682
19683         diff /etc/passwd ${other_dir}/luna ||
19684                 error "luna different after migration"
19685
19686         diff /etc/passwd ${migrate_dir}/sofia ||
19687                 error "sofia different after migration"
19688
19689         diff /etc/passwd ${other_dir}/zachary ||
19690                 error "zachary different after migration"
19691
19692         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19693                 error "${tfile}_ln different after migration"
19694
19695         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19696                 error "${tfile}_ln_other different after migration"
19697
19698         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19699         [ $stripe_count = 2 ] ||
19700                 error "dir strpe_count $d != 2 after migration."
19701
19702         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19703         [ $stripe_count = 2 ] ||
19704                 error "file strpe_count $d != 2 after migration."
19705
19706         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19707 }
19708 run_test 230b "migrate directory"
19709
19710 test_230c() {
19711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19713         remote_mds_nodsh && skip "remote MDS with nodsh"
19714         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19715                 skip "Need MDS version at least 2.11.52"
19716
19717         local MDTIDX=1
19718         local total=3
19719         local mdt_index
19720         local file
19721         local migrate_dir=$DIR/$tdir/migrate_dir
19722
19723         #If migrating directory fails in the middle, all entries of
19724         #the directory is still accessiable.
19725         test_mkdir $DIR/$tdir
19726         test_mkdir -i0 -c1 $migrate_dir
19727         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19728         stat $migrate_dir
19729         createmany -o $migrate_dir/f $total ||
19730                 error "create files under ${migrate_dir} failed"
19731
19732         # fail after migrating top dir, and this will fail only once, so the
19733         # first sub file migration will fail (currently f3), others succeed.
19734         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19735         do_facet mds1 lctl set_param fail_loc=0x1801
19736         local t=$(ls $migrate_dir | wc -l)
19737         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19738                 error "migrate should fail"
19739         local u=$(ls $migrate_dir | wc -l)
19740         [ "$u" == "$t" ] || error "$u != $t during migration"
19741
19742         # add new dir/file should succeed
19743         mkdir $migrate_dir/dir ||
19744                 error "mkdir failed under migrating directory"
19745         touch $migrate_dir/file ||
19746                 error "create file failed under migrating directory"
19747
19748         # add file with existing name should fail
19749         for file in $migrate_dir/f*; do
19750                 stat $file > /dev/null || error "stat $file failed"
19751                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19752                         error "open(O_CREAT|O_EXCL) $file should fail"
19753                 $MULTIOP $file m && error "create $file should fail"
19754                 touch $DIR/$tdir/remote_dir/$tfile ||
19755                         error "touch $tfile failed"
19756                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19757                         error "link $file should fail"
19758                 mdt_index=$($LFS getstripe -m $file)
19759                 if [ $mdt_index == 0 ]; then
19760                         # file failed to migrate is not allowed to rename to
19761                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19762                                 error "rename to $file should fail"
19763                 else
19764                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19765                                 error "rename to $file failed"
19766                 fi
19767                 echo hello >> $file || error "write $file failed"
19768         done
19769
19770         # resume migration with different options should fail
19771         $LFS migrate -m 0 $migrate_dir &&
19772                 error "migrate -m 0 $migrate_dir should fail"
19773
19774         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19775                 error "migrate -c 2 $migrate_dir should fail"
19776
19777         # resume migration should succeed
19778         $LFS migrate -m $MDTIDX $migrate_dir ||
19779                 error "migrate $migrate_dir failed"
19780
19781         echo "Finish migration, then checking.."
19782         for file in $(find $migrate_dir); do
19783                 mdt_index=$($LFS getstripe -m $file)
19784                 [ $mdt_index == $MDTIDX ] ||
19785                         error "$file is not on MDT${MDTIDX}"
19786         done
19787
19788         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19789 }
19790 run_test 230c "check directory accessiblity if migration failed"
19791
19792 test_230d() {
19793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19795         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19796                 skip "Need MDS version at least 2.11.52"
19797         # LU-11235
19798         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19799
19800         local migrate_dir=$DIR/$tdir/migrate_dir
19801         local old_index
19802         local new_index
19803         local old_count
19804         local new_count
19805         local new_hash
19806         local mdt_index
19807         local i
19808         local j
19809
19810         old_index=$((RANDOM % MDSCOUNT))
19811         old_count=$((MDSCOUNT - old_index))
19812         new_index=$((RANDOM % MDSCOUNT))
19813         new_count=$((MDSCOUNT - new_index))
19814         new_hash=1 # for all_char
19815
19816         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19817         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19818
19819         test_mkdir $DIR/$tdir
19820         test_mkdir -i $old_index -c $old_count $migrate_dir
19821
19822         for ((i=0; i<100; i++)); do
19823                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19824                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19825                         error "create files under remote dir failed $i"
19826         done
19827
19828         echo -n "Migrate from MDT$old_index "
19829         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19830         echo -n "to MDT$new_index"
19831         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19832         echo
19833
19834         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19835         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19836                 error "migrate remote dir error"
19837
19838         echo "Finish migration, then checking.."
19839         for file in $(find $migrate_dir -maxdepth 1); do
19840                 mdt_index=$($LFS getstripe -m $file)
19841                 if [ $mdt_index -lt $new_index ] ||
19842                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19843                         error "$file is on MDT$mdt_index"
19844                 fi
19845         done
19846
19847         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19848 }
19849 run_test 230d "check migrate big directory"
19850
19851 test_230e() {
19852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19854         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19855                 skip "Need MDS version at least 2.11.52"
19856
19857         local i
19858         local j
19859         local a_fid
19860         local b_fid
19861
19862         mkdir_on_mdt0 $DIR/$tdir
19863         mkdir $DIR/$tdir/migrate_dir
19864         mkdir $DIR/$tdir/other_dir
19865         touch $DIR/$tdir/migrate_dir/a
19866         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19867         ls $DIR/$tdir/other_dir
19868
19869         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19870                 error "migrate dir fails"
19871
19872         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19873         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19874
19875         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19876         [ $mdt_index == 0 ] || error "a is not on MDT0"
19877
19878         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19879                 error "migrate dir fails"
19880
19881         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19882         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19883
19884         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19885         [ $mdt_index == 1 ] || error "a is not on MDT1"
19886
19887         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19888         [ $mdt_index == 1 ] || error "b is not on MDT1"
19889
19890         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19891         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19892
19893         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19894
19895         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19896 }
19897 run_test 230e "migrate mulitple local link files"
19898
19899 test_230f() {
19900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19902         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19903                 skip "Need MDS version at least 2.11.52"
19904
19905         local a_fid
19906         local ln_fid
19907
19908         mkdir -p $DIR/$tdir
19909         mkdir $DIR/$tdir/migrate_dir
19910         $LFS mkdir -i1 $DIR/$tdir/other_dir
19911         touch $DIR/$tdir/migrate_dir/a
19912         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19913         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19914         ls $DIR/$tdir/other_dir
19915
19916         # a should be migrated to MDT1, since no other links on MDT0
19917         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19918                 error "#1 migrate dir fails"
19919         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19920         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19921         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19922         [ $mdt_index == 1 ] || error "a is not on MDT1"
19923
19924         # a should stay on MDT1, because it is a mulitple link file
19925         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19926                 error "#2 migrate dir fails"
19927         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19928         [ $mdt_index == 1 ] || error "a is not on MDT1"
19929
19930         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19931                 error "#3 migrate dir fails"
19932
19933         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19934         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19935         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19936
19937         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19938         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19939
19940         # a should be migrated to MDT0, since no other links on MDT1
19941         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19942                 error "#4 migrate dir fails"
19943         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19944         [ $mdt_index == 0 ] || error "a is not on MDT0"
19945
19946         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19947 }
19948 run_test 230f "migrate mulitple remote link files"
19949
19950 test_230g() {
19951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19952         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19953         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19954                 skip "Need MDS version at least 2.11.52"
19955
19956         mkdir -p $DIR/$tdir/migrate_dir
19957
19958         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19959                 error "migrating dir to non-exist MDT succeeds"
19960         true
19961 }
19962 run_test 230g "migrate dir to non-exist MDT"
19963
19964 test_230h() {
19965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19966         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19967         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19968                 skip "Need MDS version at least 2.11.52"
19969
19970         local mdt_index
19971
19972         mkdir -p $DIR/$tdir/migrate_dir
19973
19974         $LFS migrate -m1 $DIR &&
19975                 error "migrating mountpoint1 should fail"
19976
19977         $LFS migrate -m1 $DIR/$tdir/.. &&
19978                 error "migrating mountpoint2 should fail"
19979
19980         # same as mv
19981         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19982                 error "migrating $tdir/migrate_dir/.. should fail"
19983
19984         true
19985 }
19986 run_test 230h "migrate .. and root"
19987
19988 test_230i() {
19989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19991         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19992                 skip "Need MDS version at least 2.11.52"
19993
19994         mkdir -p $DIR/$tdir/migrate_dir
19995
19996         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19997                 error "migration fails with a tailing slash"
19998
19999         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20000                 error "migration fails with two tailing slashes"
20001 }
20002 run_test 230i "lfs migrate -m tolerates trailing slashes"
20003
20004 test_230j() {
20005         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20006         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20007                 skip "Need MDS version at least 2.11.52"
20008
20009         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20010         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20011                 error "create $tfile failed"
20012         cat /etc/passwd > $DIR/$tdir/$tfile
20013
20014         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20015
20016         cmp /etc/passwd $DIR/$tdir/$tfile ||
20017                 error "DoM file mismatch after migration"
20018 }
20019 run_test 230j "DoM file data not changed after dir migration"
20020
20021 test_230k() {
20022         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20023         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20024                 skip "Need MDS version at least 2.11.56"
20025
20026         local total=20
20027         local files_on_starting_mdt=0
20028
20029         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20030         $LFS getdirstripe $DIR/$tdir
20031         for i in $(seq $total); do
20032                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20033                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20034                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20035         done
20036
20037         echo "$files_on_starting_mdt files on MDT0"
20038
20039         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20040         $LFS getdirstripe $DIR/$tdir
20041
20042         files_on_starting_mdt=0
20043         for i in $(seq $total); do
20044                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20045                         error "file $tfile.$i mismatch after migration"
20046                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20047                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20048         done
20049
20050         echo "$files_on_starting_mdt files on MDT1 after migration"
20051         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20052
20053         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20054         $LFS getdirstripe $DIR/$tdir
20055
20056         files_on_starting_mdt=0
20057         for i in $(seq $total); do
20058                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20059                         error "file $tfile.$i mismatch after 2nd migration"
20060                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20061                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20062         done
20063
20064         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20065         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20066
20067         true
20068 }
20069 run_test 230k "file data not changed after dir migration"
20070
20071 test_230l() {
20072         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20073         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20074                 skip "Need MDS version at least 2.11.56"
20075
20076         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20077         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20078                 error "create files under remote dir failed $i"
20079         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20080 }
20081 run_test 230l "readdir between MDTs won't crash"
20082
20083 test_230m() {
20084         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20085         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20086                 skip "Need MDS version at least 2.11.56"
20087
20088         local MDTIDX=1
20089         local mig_dir=$DIR/$tdir/migrate_dir
20090         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20091         local shortstr="b"
20092         local val
20093
20094         echo "Creating files and dirs with xattrs"
20095         test_mkdir $DIR/$tdir
20096         test_mkdir -i0 -c1 $mig_dir
20097         mkdir $mig_dir/dir
20098         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20099                 error "cannot set xattr attr1 on dir"
20100         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20101                 error "cannot set xattr attr2 on dir"
20102         touch $mig_dir/dir/f0
20103         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20104                 error "cannot set xattr attr1 on file"
20105         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20106                 error "cannot set xattr attr2 on file"
20107         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20108         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20109         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20110         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20111         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20112         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20113         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20114         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20115         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20116
20117         echo "Migrating to MDT1"
20118         $LFS migrate -m $MDTIDX $mig_dir ||
20119                 error "fails on migrating dir to MDT1"
20120
20121         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20122         echo "Checking xattrs"
20123         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20124         [ "$val" = $longstr ] ||
20125                 error "expecting xattr1 $longstr on dir, found $val"
20126         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20127         [ "$val" = $shortstr ] ||
20128                 error "expecting xattr2 $shortstr on dir, found $val"
20129         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20130         [ "$val" = $longstr ] ||
20131                 error "expecting xattr1 $longstr on file, found $val"
20132         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20133         [ "$val" = $shortstr ] ||
20134                 error "expecting xattr2 $shortstr on file, found $val"
20135 }
20136 run_test 230m "xattrs not changed after dir migration"
20137
20138 test_230n() {
20139         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20140         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20141                 skip "Need MDS version at least 2.13.53"
20142
20143         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20144         cat /etc/hosts > $DIR/$tdir/$tfile
20145         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20146         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20147
20148         cmp /etc/hosts $DIR/$tdir/$tfile ||
20149                 error "File data mismatch after migration"
20150 }
20151 run_test 230n "Dir migration with mirrored file"
20152
20153 test_230o() {
20154         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20155         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20156                 skip "Need MDS version at least 2.13.52"
20157
20158         local mdts=$(comma_list $(mdts_nodes))
20159         local timeout=100
20160         local restripe_status
20161         local delta
20162         local i
20163
20164         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20165
20166         # in case "crush" hash type is not set
20167         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20168
20169         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20170                            mdt.*MDT0000.enable_dir_restripe)
20171         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20172         stack_trap "do_nodes $mdts $LCTL set_param \
20173                     mdt.*.enable_dir_restripe=$restripe_status"
20174
20175         mkdir $DIR/$tdir
20176         createmany -m $DIR/$tdir/f 100 ||
20177                 error "create files under remote dir failed $i"
20178         createmany -d $DIR/$tdir/d 100 ||
20179                 error "create dirs under remote dir failed $i"
20180
20181         for i in $(seq 2 $MDSCOUNT); do
20182                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20183                 $LFS setdirstripe -c $i $DIR/$tdir ||
20184                         error "split -c $i $tdir failed"
20185                 wait_update $HOSTNAME \
20186                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20187                         error "dir split not finished"
20188                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20189                         awk '/migrate/ {sum += $2} END { print sum }')
20190                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20191                 # delta is around total_files/stripe_count
20192                 (( $delta < 200 / (i - 1) + 4 )) ||
20193                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20194         done
20195 }
20196 run_test 230o "dir split"
20197
20198 test_230p() {
20199         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20200         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20201                 skip "Need MDS version at least 2.13.52"
20202
20203         local mdts=$(comma_list $(mdts_nodes))
20204         local timeout=100
20205         local restripe_status
20206         local delta
20207         local c
20208
20209         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20210
20211         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20212
20213         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20214                            mdt.*MDT0000.enable_dir_restripe)
20215         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20216         stack_trap "do_nodes $mdts $LCTL set_param \
20217                     mdt.*.enable_dir_restripe=$restripe_status"
20218
20219         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20220         createmany -m $DIR/$tdir/f 100 ||
20221                 error "create files under remote dir failed"
20222         createmany -d $DIR/$tdir/d 100 ||
20223                 error "create dirs under remote dir failed"
20224
20225         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20226                 local mdt_hash="crush"
20227
20228                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20229                 $LFS setdirstripe -c $c $DIR/$tdir ||
20230                         error "split -c $c $tdir failed"
20231                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20232                         mdt_hash="$mdt_hash,fixed"
20233                 elif [ $c -eq 1 ]; then
20234                         mdt_hash="none"
20235                 fi
20236                 wait_update $HOSTNAME \
20237                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20238                         error "dir merge not finished"
20239                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20240                         awk '/migrate/ {sum += $2} END { print sum }')
20241                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20242                 # delta is around total_files/stripe_count
20243                 (( delta < 200 / c + 4 )) ||
20244                         error "$delta files migrated >= $((200 / c + 4))"
20245         done
20246 }
20247 run_test 230p "dir merge"
20248
20249 test_230q() {
20250         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20251         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20252                 skip "Need MDS version at least 2.13.52"
20253
20254         local mdts=$(comma_list $(mdts_nodes))
20255         local saved_threshold=$(do_facet mds1 \
20256                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20257         local saved_delta=$(do_facet mds1 \
20258                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20259         local threshold=100
20260         local delta=2
20261         local total=0
20262         local stripe_count=0
20263         local stripe_index
20264         local nr_files
20265         local create
20266
20267         # test with fewer files on ZFS
20268         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20269
20270         stack_trap "do_nodes $mdts $LCTL set_param \
20271                     mdt.*.dir_split_count=$saved_threshold"
20272         stack_trap "do_nodes $mdts $LCTL set_param \
20273                     mdt.*.dir_split_delta=$saved_delta"
20274         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20275         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20276         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20277         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20278         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20279         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20280
20281         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20282         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20283
20284         create=$((threshold * 3 / 2))
20285         while [ $stripe_count -lt $MDSCOUNT ]; do
20286                 createmany -m $DIR/$tdir/f $total $create ||
20287                         error "create sub files failed"
20288                 stat $DIR/$tdir > /dev/null
20289                 total=$((total + create))
20290                 stripe_count=$((stripe_count + delta))
20291                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20292
20293                 wait_update $HOSTNAME \
20294                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20295                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20296
20297                 wait_update $HOSTNAME \
20298                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20299                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20300
20301                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20302                 echo "$nr_files/$total files on MDT$stripe_index after split"
20303                 # allow 10% margin of imbalance with crush hash
20304                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20305                         error "$nr_files files on MDT$stripe_index after split"
20306
20307                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20308                 [ $nr_files -eq $total ] ||
20309                         error "total sub files $nr_files != $total"
20310         done
20311
20312         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20313
20314         echo "fixed layout directory won't auto split"
20315         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20316         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20317                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20318         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20319                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20320 }
20321 run_test 230q "dir auto split"
20322
20323 test_230r() {
20324         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20325         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20326         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20327                 skip "Need MDS version at least 2.13.54"
20328
20329         # maximum amount of local locks:
20330         # parent striped dir - 2 locks
20331         # new stripe in parent to migrate to - 1 lock
20332         # source and target - 2 locks
20333         # Total 5 locks for regular file
20334         mkdir -p $DIR/$tdir
20335         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20336         touch $DIR/$tdir/dir1/eee
20337
20338         # create 4 hardlink for 4 more locks
20339         # Total: 9 locks > RS_MAX_LOCKS (8)
20340         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20341         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20342         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20343         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20344         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20345         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20346         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20347         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20348
20349         cancel_lru_locks mdc
20350
20351         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20352                 error "migrate dir fails"
20353
20354         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20355 }
20356 run_test 230r "migrate with too many local locks"
20357
20358 test_230s() {
20359         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20360                 skip "Need MDS version at least 2.13.57"
20361
20362         local mdts=$(comma_list $(mdts_nodes))
20363         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20364                                 mdt.*MDT0000.enable_dir_restripe)
20365
20366         stack_trap "do_nodes $mdts $LCTL set_param \
20367                     mdt.*.enable_dir_restripe=$restripe_status"
20368
20369         local st
20370         for st in 0 1; do
20371                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20372                 test_mkdir $DIR/$tdir
20373                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20374                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20375                 rmdir $DIR/$tdir
20376         done
20377 }
20378 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20379
20380 test_230t()
20381 {
20382         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20383         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20384                 skip "Need MDS version at least 2.14.50"
20385
20386         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20387         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20388         $LFS project -p 1 -s $DIR/$tdir ||
20389                 error "set $tdir project id failed"
20390         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20391                 error "set subdir project id failed"
20392         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20393 }
20394 run_test 230t "migrate directory with project ID set"
20395
20396 test_230u()
20397 {
20398         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20399         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20400                 skip "Need MDS version at least 2.14.53"
20401
20402         local count
20403
20404         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20405         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20406         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20407         for i in $(seq 0 $((MDSCOUNT - 1))); do
20408                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20409                 echo "$count dirs migrated to MDT$i"
20410         done
20411         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20412         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20413 }
20414 run_test 230u "migrate directory by QOS"
20415
20416 test_230v()
20417 {
20418         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20419         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20420                 skip "Need MDS version at least 2.14.53"
20421
20422         local count
20423
20424         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20425         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20426         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20427         for i in $(seq 0 $((MDSCOUNT - 1))); do
20428                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20429                 echo "$count subdirs migrated to MDT$i"
20430                 (( i == 3 )) && (( count > 0 )) &&
20431                         error "subdir shouldn't be migrated to MDT3"
20432         done
20433         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20434         (( count == 3 )) || error "dirs migrated to $count MDTs"
20435 }
20436 run_test 230v "subdir migrated to the MDT where its parent is located"
20437
20438 test_230w() {
20439         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20440         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20441                 skip "Need MDS version at least 2.14.53"
20442
20443         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20444
20445         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20446                 error "migrate failed"
20447
20448         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20449                 error "$tdir stripe count mismatch"
20450
20451         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20452                 error "$tdir/sub is striped"
20453 }
20454 run_test 230w "non-recursive mode dir migration"
20455
20456 test_231a()
20457 {
20458         # For simplicity this test assumes that max_pages_per_rpc
20459         # is the same across all OSCs
20460         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20461         local bulk_size=$((max_pages * PAGE_SIZE))
20462         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20463                                        head -n 1)
20464
20465         mkdir -p $DIR/$tdir
20466         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20467                 error "failed to set stripe with -S ${brw_size}M option"
20468
20469         # clear the OSC stats
20470         $LCTL set_param osc.*.stats=0 &>/dev/null
20471         stop_writeback
20472
20473         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20474         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20475                 oflag=direct &>/dev/null || error "dd failed"
20476
20477         sync; sleep 1; sync # just to be safe
20478         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20479         if [ x$nrpcs != "x1" ]; then
20480                 $LCTL get_param osc.*.stats
20481                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20482         fi
20483
20484         start_writeback
20485         # Drop the OSC cache, otherwise we will read from it
20486         cancel_lru_locks osc
20487
20488         # clear the OSC stats
20489         $LCTL set_param osc.*.stats=0 &>/dev/null
20490
20491         # Client reads $bulk_size.
20492         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20493                 iflag=direct &>/dev/null || error "dd failed"
20494
20495         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20496         if [ x$nrpcs != "x1" ]; then
20497                 $LCTL get_param osc.*.stats
20498                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20499         fi
20500 }
20501 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20502
20503 test_231b() {
20504         mkdir -p $DIR/$tdir
20505         local i
20506         for i in {0..1023}; do
20507                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20508                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20509                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20510         done
20511         sync
20512 }
20513 run_test 231b "must not assert on fully utilized OST request buffer"
20514
20515 test_232a() {
20516         mkdir -p $DIR/$tdir
20517         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20518
20519         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20520         do_facet ost1 $LCTL set_param fail_loc=0x31c
20521
20522         # ignore dd failure
20523         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20524
20525         do_facet ost1 $LCTL set_param fail_loc=0
20526         umount_client $MOUNT || error "umount failed"
20527         mount_client $MOUNT || error "mount failed"
20528         stop ost1 || error "cannot stop ost1"
20529         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20530 }
20531 run_test 232a "failed lock should not block umount"
20532
20533 test_232b() {
20534         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20535                 skip "Need MDS version at least 2.10.58"
20536
20537         mkdir -p $DIR/$tdir
20538         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20539         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20540         sync
20541         cancel_lru_locks osc
20542
20543         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20544         do_facet ost1 $LCTL set_param fail_loc=0x31c
20545
20546         # ignore failure
20547         $LFS data_version $DIR/$tdir/$tfile || true
20548
20549         do_facet ost1 $LCTL set_param fail_loc=0
20550         umount_client $MOUNT || error "umount failed"
20551         mount_client $MOUNT || error "mount failed"
20552         stop ost1 || error "cannot stop ost1"
20553         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20554 }
20555 run_test 232b "failed data version lock should not block umount"
20556
20557 test_233a() {
20558         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20559                 skip "Need MDS version at least 2.3.64"
20560         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20561
20562         local fid=$($LFS path2fid $MOUNT)
20563
20564         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20565                 error "cannot access $MOUNT using its FID '$fid'"
20566 }
20567 run_test 233a "checking that OBF of the FS root succeeds"
20568
20569 test_233b() {
20570         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20571                 skip "Need MDS version at least 2.5.90"
20572         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20573
20574         local fid=$($LFS path2fid $MOUNT/.lustre)
20575
20576         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20577                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20578
20579         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20580         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20581                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20582 }
20583 run_test 233b "checking that OBF of the FS .lustre succeeds"
20584
20585 test_234() {
20586         local p="$TMP/sanityN-$TESTNAME.parameters"
20587         save_lustre_params client "llite.*.xattr_cache" > $p
20588         lctl set_param llite.*.xattr_cache 1 ||
20589                 skip_env "xattr cache is not supported"
20590
20591         mkdir -p $DIR/$tdir || error "mkdir failed"
20592         touch $DIR/$tdir/$tfile || error "touch failed"
20593         # OBD_FAIL_LLITE_XATTR_ENOMEM
20594         $LCTL set_param fail_loc=0x1405
20595         getfattr -n user.attr $DIR/$tdir/$tfile &&
20596                 error "getfattr should have failed with ENOMEM"
20597         $LCTL set_param fail_loc=0x0
20598         rm -rf $DIR/$tdir
20599
20600         restore_lustre_params < $p
20601         rm -f $p
20602 }
20603 run_test 234 "xattr cache should not crash on ENOMEM"
20604
20605 test_235() {
20606         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20607                 skip "Need MDS version at least 2.4.52"
20608
20609         flock_deadlock $DIR/$tfile
20610         local RC=$?
20611         case $RC in
20612                 0)
20613                 ;;
20614                 124) error "process hangs on a deadlock"
20615                 ;;
20616                 *) error "error executing flock_deadlock $DIR/$tfile"
20617                 ;;
20618         esac
20619 }
20620 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20621
20622 #LU-2935
20623 test_236() {
20624         check_swap_layouts_support
20625
20626         local ref1=/etc/passwd
20627         local ref2=/etc/group
20628         local file1=$DIR/$tdir/f1
20629         local file2=$DIR/$tdir/f2
20630
20631         test_mkdir -c1 $DIR/$tdir
20632         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20633         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20634         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20635         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20636         local fd=$(free_fd)
20637         local cmd="exec $fd<>$file2"
20638         eval $cmd
20639         rm $file2
20640         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20641                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20642         cmd="exec $fd>&-"
20643         eval $cmd
20644         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20645
20646         #cleanup
20647         rm -rf $DIR/$tdir
20648 }
20649 run_test 236 "Layout swap on open unlinked file"
20650
20651 # LU-4659 linkea consistency
20652 test_238() {
20653         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20654                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20655                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20656                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20657
20658         touch $DIR/$tfile
20659         ln $DIR/$tfile $DIR/$tfile.lnk
20660         touch $DIR/$tfile.new
20661         mv $DIR/$tfile.new $DIR/$tfile
20662         local fid1=$($LFS path2fid $DIR/$tfile)
20663         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20664         local path1=$($LFS fid2path $FSNAME "$fid1")
20665         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20666         local path2=$($LFS fid2path $FSNAME "$fid2")
20667         [ $tfile.lnk == $path2 ] ||
20668                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20669         rm -f $DIR/$tfile*
20670 }
20671 run_test 238 "Verify linkea consistency"
20672
20673 test_239A() { # was test_239
20674         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20675                 skip "Need MDS version at least 2.5.60"
20676
20677         local list=$(comma_list $(mdts_nodes))
20678
20679         mkdir -p $DIR/$tdir
20680         createmany -o $DIR/$tdir/f- 5000
20681         unlinkmany $DIR/$tdir/f- 5000
20682         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20683                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20684         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20685                         osp.*MDT*.sync_in_flight" | calc_sum)
20686         [ "$changes" -eq 0 ] || error "$changes not synced"
20687 }
20688 run_test 239A "osp_sync test"
20689
20690 test_239a() { #LU-5297
20691         remote_mds_nodsh && skip "remote MDS with nodsh"
20692
20693         touch $DIR/$tfile
20694         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20695         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20696         chgrp $RUNAS_GID $DIR/$tfile
20697         wait_delete_completed
20698 }
20699 run_test 239a "process invalid osp sync record correctly"
20700
20701 test_239b() { #LU-5297
20702         remote_mds_nodsh && skip "remote MDS with nodsh"
20703
20704         touch $DIR/$tfile1
20705         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20706         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20707         chgrp $RUNAS_GID $DIR/$tfile1
20708         wait_delete_completed
20709         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20710         touch $DIR/$tfile2
20711         chgrp $RUNAS_GID $DIR/$tfile2
20712         wait_delete_completed
20713 }
20714 run_test 239b "process osp sync record with ENOMEM error correctly"
20715
20716 test_240() {
20717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20718         remote_mds_nodsh && skip "remote MDS with nodsh"
20719
20720         mkdir -p $DIR/$tdir
20721
20722         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20723                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20724         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20725                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20726
20727         umount_client $MOUNT || error "umount failed"
20728         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20729         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20730         mount_client $MOUNT || error "failed to mount client"
20731
20732         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20733         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20734 }
20735 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20736
20737 test_241_bio() {
20738         local count=$1
20739         local bsize=$2
20740
20741         for LOOP in $(seq $count); do
20742                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20743                 cancel_lru_locks $OSC || true
20744         done
20745 }
20746
20747 test_241_dio() {
20748         local count=$1
20749         local bsize=$2
20750
20751         for LOOP in $(seq $1); do
20752                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20753                         2>/dev/null
20754         done
20755 }
20756
20757 test_241a() { # was test_241
20758         local bsize=$PAGE_SIZE
20759
20760         (( bsize < 40960 )) && bsize=40960
20761         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20762         ls -la $DIR/$tfile
20763         cancel_lru_locks $OSC
20764         test_241_bio 1000 $bsize &
20765         PID=$!
20766         test_241_dio 1000 $bsize
20767         wait $PID
20768 }
20769 run_test 241a "bio vs dio"
20770
20771 test_241b() {
20772         local bsize=$PAGE_SIZE
20773
20774         (( bsize < 40960 )) && bsize=40960
20775         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20776         ls -la $DIR/$tfile
20777         test_241_dio 1000 $bsize &
20778         PID=$!
20779         test_241_dio 1000 $bsize
20780         wait $PID
20781 }
20782 run_test 241b "dio vs dio"
20783
20784 test_242() {
20785         remote_mds_nodsh && skip "remote MDS with nodsh"
20786
20787         mkdir_on_mdt0 $DIR/$tdir
20788         touch $DIR/$tdir/$tfile
20789
20790         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20791         do_facet mds1 lctl set_param fail_loc=0x105
20792         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20793
20794         do_facet mds1 lctl set_param fail_loc=0
20795         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20796 }
20797 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20798
20799 test_243()
20800 {
20801         test_mkdir $DIR/$tdir
20802         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20803 }
20804 run_test 243 "various group lock tests"
20805
20806 test_244a()
20807 {
20808         test_mkdir $DIR/$tdir
20809         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20810         sendfile_grouplock $DIR/$tdir/$tfile || \
20811                 error "sendfile+grouplock failed"
20812         rm -rf $DIR/$tdir
20813 }
20814 run_test 244a "sendfile with group lock tests"
20815
20816 test_244b()
20817 {
20818         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20819
20820         local threads=50
20821         local size=$((1024*1024))
20822
20823         test_mkdir $DIR/$tdir
20824         for i in $(seq 1 $threads); do
20825                 local file=$DIR/$tdir/file_$((i / 10))
20826                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20827                 local pids[$i]=$!
20828         done
20829         for i in $(seq 1 $threads); do
20830                 wait ${pids[$i]}
20831         done
20832 }
20833 run_test 244b "multi-threaded write with group lock"
20834
20835 test_245() {
20836         local flagname="multi_mod_rpcs"
20837         local connect_data_name="max_mod_rpcs"
20838         local out
20839
20840         # check if multiple modify RPCs flag is set
20841         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20842                 grep "connect_flags:")
20843         echo "$out"
20844
20845         echo "$out" | grep -qw $flagname
20846         if [ $? -ne 0 ]; then
20847                 echo "connect flag $flagname is not set"
20848                 return
20849         fi
20850
20851         # check if multiple modify RPCs data is set
20852         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20853         echo "$out"
20854
20855         echo "$out" | grep -qw $connect_data_name ||
20856                 error "import should have connect data $connect_data_name"
20857 }
20858 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20859
20860 cleanup_247() {
20861         local submount=$1
20862
20863         trap 0
20864         umount_client $submount
20865         rmdir $submount
20866 }
20867
20868 test_247a() {
20869         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20870                 grep -q subtree ||
20871                 skip_env "Fileset feature is not supported"
20872
20873         local submount=${MOUNT}_$tdir
20874
20875         mkdir $MOUNT/$tdir
20876         mkdir -p $submount || error "mkdir $submount failed"
20877         FILESET="$FILESET/$tdir" mount_client $submount ||
20878                 error "mount $submount failed"
20879         trap "cleanup_247 $submount" EXIT
20880         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20881         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20882                 error "read $MOUNT/$tdir/$tfile failed"
20883         cleanup_247 $submount
20884 }
20885 run_test 247a "mount subdir as fileset"
20886
20887 test_247b() {
20888         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20889                 skip_env "Fileset feature is not supported"
20890
20891         local submount=${MOUNT}_$tdir
20892
20893         rm -rf $MOUNT/$tdir
20894         mkdir -p $submount || error "mkdir $submount failed"
20895         SKIP_FILESET=1
20896         FILESET="$FILESET/$tdir" mount_client $submount &&
20897                 error "mount $submount should fail"
20898         rmdir $submount
20899 }
20900 run_test 247b "mount subdir that dose not exist"
20901
20902 test_247c() {
20903         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20904                 skip_env "Fileset feature is not supported"
20905
20906         local submount=${MOUNT}_$tdir
20907
20908         mkdir -p $MOUNT/$tdir/dir1
20909         mkdir -p $submount || error "mkdir $submount failed"
20910         trap "cleanup_247 $submount" EXIT
20911         FILESET="$FILESET/$tdir" mount_client $submount ||
20912                 error "mount $submount failed"
20913         local fid=$($LFS path2fid $MOUNT/)
20914         $LFS fid2path $submount $fid && error "fid2path should fail"
20915         cleanup_247 $submount
20916 }
20917 run_test 247c "running fid2path outside subdirectory root"
20918
20919 test_247d() {
20920         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20921                 skip "Fileset feature is not supported"
20922
20923         local submount=${MOUNT}_$tdir
20924
20925         mkdir -p $MOUNT/$tdir/dir1
20926         mkdir -p $submount || error "mkdir $submount failed"
20927         FILESET="$FILESET/$tdir" mount_client $submount ||
20928                 error "mount $submount failed"
20929         trap "cleanup_247 $submount" EXIT
20930
20931         local td=$submount/dir1
20932         local fid=$($LFS path2fid $td)
20933         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20934
20935         # check that we get the same pathname back
20936         local rootpath
20937         local found
20938         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20939                 echo "$rootpath $fid"
20940                 found=$($LFS fid2path $rootpath "$fid")
20941                 [ -n "found" ] || error "fid2path should succeed"
20942                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20943         done
20944         # check wrong root path format
20945         rootpath=$submount"_wrong"
20946         found=$($LFS fid2path $rootpath "$fid")
20947         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20948
20949         cleanup_247 $submount
20950 }
20951 run_test 247d "running fid2path inside subdirectory root"
20952
20953 # LU-8037
20954 test_247e() {
20955         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20956                 grep -q subtree ||
20957                 skip "Fileset feature is not supported"
20958
20959         local submount=${MOUNT}_$tdir
20960
20961         mkdir $MOUNT/$tdir
20962         mkdir -p $submount || error "mkdir $submount failed"
20963         FILESET="$FILESET/.." mount_client $submount &&
20964                 error "mount $submount should fail"
20965         rmdir $submount
20966 }
20967 run_test 247e "mount .. as fileset"
20968
20969 test_247f() {
20970         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20971         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20972                 skip "Need at least version 2.13.52"
20973         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20974                 skip "Need at least version 2.14.50"
20975         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20976                 grep -q subtree ||
20977                 skip "Fileset feature is not supported"
20978
20979         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20980         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20981                 error "mkdir remote failed"
20982         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20983                 error "mkdir remote/subdir failed"
20984         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20985                 error "mkdir striped failed"
20986         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20987
20988         local submount=${MOUNT}_$tdir
20989
20990         mkdir -p $submount || error "mkdir $submount failed"
20991         stack_trap "rmdir $submount"
20992
20993         local dir
20994         local stat
20995         local fileset=$FILESET
20996         local mdts=$(comma_list $(mdts_nodes))
20997
20998         stat=$(do_facet mds1 $LCTL get_param -n \
20999                 mdt.*MDT0000.enable_remote_subdir_mount)
21000         stack_trap "do_nodes $mdts $LCTL set_param \
21001                 mdt.*.enable_remote_subdir_mount=$stat"
21002
21003         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21004         stack_trap "umount_client $submount"
21005         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21006                 error "mount remote dir $dir should fail"
21007
21008         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21009                 $tdir/striped/. ; do
21010                 FILESET="$fileset/$dir" mount_client $submount ||
21011                         error "mount $dir failed"
21012                 umount_client $submount
21013         done
21014
21015         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21016         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21017                 error "mount $tdir/remote failed"
21018 }
21019 run_test 247f "mount striped or remote directory as fileset"
21020
21021 test_247g() {
21022         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21023         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21024                 skip "Need at least version 2.14.50"
21025
21026         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21027                 error "mkdir $tdir failed"
21028         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21029
21030         local submount=${MOUNT}_$tdir
21031
21032         mkdir -p $submount || error "mkdir $submount failed"
21033         stack_trap "rmdir $submount"
21034
21035         FILESET="$fileset/$tdir" mount_client $submount ||
21036                 error "mount $dir failed"
21037         stack_trap "umount $submount"
21038
21039         local mdts=$(comma_list $(mdts_nodes))
21040
21041         local nrpcs
21042
21043         stat $submount > /dev/null
21044         cancel_lru_locks $MDC
21045         stat $submount > /dev/null
21046         stat $submount/$tfile > /dev/null
21047         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21048         stat $submount/$tfile > /dev/null
21049         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21050                 awk '/getattr/ {sum += $2} END {print sum}')
21051
21052         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21053 }
21054 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21055
21056 test_248a() {
21057         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21058         [ -z "$fast_read_sav" ] && skip "no fast read support"
21059
21060         # create a large file for fast read verification
21061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21062
21063         # make sure the file is created correctly
21064         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21065                 { rm -f $DIR/$tfile; skip "file creation error"; }
21066
21067         echo "Test 1: verify that fast read is 4 times faster on cache read"
21068
21069         # small read with fast read enabled
21070         $LCTL set_param -n llite.*.fast_read=1
21071         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21072                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21073                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21074         # small read with fast read disabled
21075         $LCTL set_param -n llite.*.fast_read=0
21076         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21077                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21078                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21079
21080         # verify that fast read is 4 times faster for cache read
21081         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21082                 error_not_in_vm "fast read was not 4 times faster: " \
21083                            "$t_fast vs $t_slow"
21084
21085         echo "Test 2: verify the performance between big and small read"
21086         $LCTL set_param -n llite.*.fast_read=1
21087
21088         # 1k non-cache read
21089         cancel_lru_locks osc
21090         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21091                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21092                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21093
21094         # 1M non-cache read
21095         cancel_lru_locks osc
21096         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21097                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21098                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21099
21100         # verify that big IO is not 4 times faster than small IO
21101         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21102                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21103
21104         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21105         rm -f $DIR/$tfile
21106 }
21107 run_test 248a "fast read verification"
21108
21109 test_248b() {
21110         # Default short_io_bytes=16384, try both smaller and larger sizes.
21111         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21112         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21113         echo "bs=53248 count=113 normal buffered write"
21114         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21115                 error "dd of initial data file failed"
21116         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21117
21118         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21119         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21120                 error "dd with sync normal writes failed"
21121         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21122
21123         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21124         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21125                 error "dd with sync small writes failed"
21126         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21127
21128         cancel_lru_locks osc
21129
21130         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21131         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21132         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21133         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21134                 iflag=direct || error "dd with O_DIRECT small read failed"
21135         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21136         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21137                 error "compare $TMP/$tfile.1 failed"
21138
21139         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21140         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21141
21142         # just to see what the maximum tunable value is, and test parsing
21143         echo "test invalid parameter 2MB"
21144         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21145                 error "too-large short_io_bytes allowed"
21146         echo "test maximum parameter 512KB"
21147         # if we can set a larger short_io_bytes, run test regardless of version
21148         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21149                 # older clients may not allow setting it this large, that's OK
21150                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21151                         skip "Need at least client version 2.13.50"
21152                 error "medium short_io_bytes failed"
21153         fi
21154         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21155         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21156
21157         echo "test large parameter 64KB"
21158         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21159         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21160
21161         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21162         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21163                 error "dd with sync large writes failed"
21164         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21165
21166         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21167         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21168         num=$((113 * 4096 / PAGE_SIZE))
21169         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21170         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21171                 error "dd with O_DIRECT large writes failed"
21172         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21173                 error "compare $DIR/$tfile.3 failed"
21174
21175         cancel_lru_locks osc
21176
21177         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21178         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21179                 error "dd with O_DIRECT large read failed"
21180         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21181                 error "compare $TMP/$tfile.2 failed"
21182
21183         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21184         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21185                 error "dd with O_DIRECT large read failed"
21186         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21187                 error "compare $TMP/$tfile.3 failed"
21188 }
21189 run_test 248b "test short_io read and write for both small and large sizes"
21190
21191 test_249() { # LU-7890
21192         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21193                 skip "Need at least version 2.8.54"
21194
21195         rm -f $DIR/$tfile
21196         $LFS setstripe -c 1 $DIR/$tfile
21197         # Offset 2T == 4k * 512M
21198         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21199                 error "dd to 2T offset failed"
21200 }
21201 run_test 249 "Write above 2T file size"
21202
21203 test_250() {
21204         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21205          && skip "no 16TB file size limit on ZFS"
21206
21207         $LFS setstripe -c 1 $DIR/$tfile
21208         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21209         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21210         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21211         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21212                 conv=notrunc,fsync && error "append succeeded"
21213         return 0
21214 }
21215 run_test 250 "Write above 16T limit"
21216
21217 test_251() {
21218         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21219
21220         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21221         #Skip once - writing the first stripe will succeed
21222         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21223         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21224                 error "short write happened"
21225
21226         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21227         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21228                 error "short read happened"
21229
21230         rm -f $DIR/$tfile
21231 }
21232 run_test 251 "Handling short read and write correctly"
21233
21234 test_252() {
21235         remote_mds_nodsh && skip "remote MDS with nodsh"
21236         remote_ost_nodsh && skip "remote OST with nodsh"
21237         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21238                 skip_env "ldiskfs only test"
21239         fi
21240
21241         local tgt
21242         local dev
21243         local out
21244         local uuid
21245         local num
21246         local gen
21247
21248         # check lr_reader on OST0000
21249         tgt=ost1
21250         dev=$(facet_device $tgt)
21251         out=$(do_facet $tgt $LR_READER $dev)
21252         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21253         echo "$out"
21254         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21255         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21256                 error "Invalid uuid returned by $LR_READER on target $tgt"
21257         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21258
21259         # check lr_reader -c on MDT0000
21260         tgt=mds1
21261         dev=$(facet_device $tgt)
21262         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21263                 skip "$LR_READER does not support additional options"
21264         fi
21265         out=$(do_facet $tgt $LR_READER -c $dev)
21266         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21267         echo "$out"
21268         num=$(echo "$out" | grep -c "mdtlov")
21269         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21270                 error "Invalid number of mdtlov clients returned by $LR_READER"
21271         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21272
21273         # check lr_reader -cr on MDT0000
21274         out=$(do_facet $tgt $LR_READER -cr $dev)
21275         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21276         echo "$out"
21277         echo "$out" | grep -q "^reply_data:$" ||
21278                 error "$LR_READER should have returned 'reply_data' section"
21279         num=$(echo "$out" | grep -c "client_generation")
21280         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21281 }
21282 run_test 252 "check lr_reader tool"
21283
21284 test_253() {
21285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21286         remote_mds_nodsh && skip "remote MDS with nodsh"
21287         remote_mgs_nodsh && skip "remote MGS with nodsh"
21288
21289         local ostidx=0
21290         local rc=0
21291         local ost_name=$(ostname_from_index $ostidx)
21292
21293         # on the mdt's osc
21294         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21295         do_facet $SINGLEMDS $LCTL get_param -n \
21296                 osp.$mdtosc_proc1.reserved_mb_high ||
21297                 skip  "remote MDS does not support reserved_mb_high"
21298
21299         rm -rf $DIR/$tdir
21300         wait_mds_ost_sync
21301         wait_delete_completed
21302         mkdir $DIR/$tdir
21303
21304         pool_add $TESTNAME || error "Pool creation failed"
21305         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21306
21307         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21308                 error "Setstripe failed"
21309
21310         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21311
21312         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21313                     grep "watermarks")
21314         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21315
21316         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21317                         osp.$mdtosc_proc1.prealloc_status)
21318         echo "prealloc_status $oa_status"
21319
21320         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21321                 error "File creation should fail"
21322
21323         #object allocation was stopped, but we still able to append files
21324         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21325                 oflag=append || error "Append failed"
21326
21327         rm -f $DIR/$tdir/$tfile.0
21328
21329         # For this test, we want to delete the files we created to go out of
21330         # space but leave the watermark, so we remain nearly out of space
21331         ost_watermarks_enospc_delete_files $tfile $ostidx
21332
21333         wait_delete_completed
21334
21335         sleep_maxage
21336
21337         for i in $(seq 10 12); do
21338                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21339                         2>/dev/null || error "File creation failed after rm"
21340         done
21341
21342         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21343                         osp.$mdtosc_proc1.prealloc_status)
21344         echo "prealloc_status $oa_status"
21345
21346         if (( oa_status != 0 )); then
21347                 error "Object allocation still disable after rm"
21348         fi
21349 }
21350 run_test 253 "Check object allocation limit"
21351
21352 test_254() {
21353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21354         remote_mds_nodsh && skip "remote MDS with nodsh"
21355
21356         local mdt=$(facet_svc $SINGLEMDS)
21357
21358         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21359                 skip "MDS does not support changelog_size"
21360
21361         local cl_user
21362
21363         changelog_register || error "changelog_register failed"
21364
21365         changelog_clear 0 || error "changelog_clear failed"
21366
21367         local size1=$(do_facet $SINGLEMDS \
21368                       $LCTL get_param -n mdd.$mdt.changelog_size)
21369         echo "Changelog size $size1"
21370
21371         rm -rf $DIR/$tdir
21372         $LFS mkdir -i 0 $DIR/$tdir
21373         # change something
21374         mkdir -p $DIR/$tdir/pics/2008/zachy
21375         touch $DIR/$tdir/pics/2008/zachy/timestamp
21376         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21377         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21378         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21379         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21380         rm $DIR/$tdir/pics/desktop.jpg
21381
21382         local size2=$(do_facet $SINGLEMDS \
21383                       $LCTL get_param -n mdd.$mdt.changelog_size)
21384         echo "Changelog size after work $size2"
21385
21386         (( $size2 > $size1 )) ||
21387                 error "new Changelog size=$size2 less than old size=$size1"
21388 }
21389 run_test 254 "Check changelog size"
21390
21391 ladvise_no_type()
21392 {
21393         local type=$1
21394         local file=$2
21395
21396         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21397                 awk -F: '{print $2}' | grep $type > /dev/null
21398         if [ $? -ne 0 ]; then
21399                 return 0
21400         fi
21401         return 1
21402 }
21403
21404 ladvise_no_ioctl()
21405 {
21406         local file=$1
21407
21408         lfs ladvise -a willread $file > /dev/null 2>&1
21409         if [ $? -eq 0 ]; then
21410                 return 1
21411         fi
21412
21413         lfs ladvise -a willread $file 2>&1 |
21414                 grep "Inappropriate ioctl for device" > /dev/null
21415         if [ $? -eq 0 ]; then
21416                 return 0
21417         fi
21418         return 1
21419 }
21420
21421 percent() {
21422         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21423 }
21424
21425 # run a random read IO workload
21426 # usage: random_read_iops <filename> <filesize> <iosize>
21427 random_read_iops() {
21428         local file=$1
21429         local fsize=$2
21430         local iosize=${3:-4096}
21431
21432         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21433                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21434 }
21435
21436 drop_file_oss_cache() {
21437         local file="$1"
21438         local nodes="$2"
21439
21440         $LFS ladvise -a dontneed $file 2>/dev/null ||
21441                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21442 }
21443
21444 ladvise_willread_performance()
21445 {
21446         local repeat=10
21447         local average_origin=0
21448         local average_cache=0
21449         local average_ladvise=0
21450
21451         for ((i = 1; i <= $repeat; i++)); do
21452                 echo "Iter $i/$repeat: reading without willread hint"
21453                 cancel_lru_locks osc
21454                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21455                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21456                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21457                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21458
21459                 cancel_lru_locks osc
21460                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21461                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21462                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21463
21464                 cancel_lru_locks osc
21465                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21466                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21467                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21468                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21469                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21470         done
21471         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21472         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21473         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21474
21475         speedup_cache=$(percent $average_cache $average_origin)
21476         speedup_ladvise=$(percent $average_ladvise $average_origin)
21477
21478         echo "Average uncached read: $average_origin"
21479         echo "Average speedup with OSS cached read: " \
21480                 "$average_cache = +$speedup_cache%"
21481         echo "Average speedup with ladvise willread: " \
21482                 "$average_ladvise = +$speedup_ladvise%"
21483
21484         local lowest_speedup=20
21485         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21486                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21487                         "got $average_cache%. Skipping ladvise willread check."
21488                 return 0
21489         fi
21490
21491         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21492         # it is still good to run until then to exercise 'ladvise willread'
21493         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21494                 [ "$ost1_FSTYPE" = "zfs" ] &&
21495                 echo "osd-zfs does not support dontneed or drop_caches" &&
21496                 return 0
21497
21498         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21499         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21500                 error_not_in_vm "Speedup with willread is less than " \
21501                         "$lowest_speedup%, got $average_ladvise%"
21502 }
21503
21504 test_255a() {
21505         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21506                 skip "lustre < 2.8.54 does not support ladvise "
21507         remote_ost_nodsh && skip "remote OST with nodsh"
21508
21509         stack_trap "rm -f $DIR/$tfile"
21510         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21511
21512         ladvise_no_type willread $DIR/$tfile &&
21513                 skip "willread ladvise is not supported"
21514
21515         ladvise_no_ioctl $DIR/$tfile &&
21516                 skip "ladvise ioctl is not supported"
21517
21518         local size_mb=100
21519         local size=$((size_mb * 1048576))
21520         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21521                 error "dd to $DIR/$tfile failed"
21522
21523         lfs ladvise -a willread $DIR/$tfile ||
21524                 error "Ladvise failed with no range argument"
21525
21526         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21527                 error "Ladvise failed with no -l or -e argument"
21528
21529         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21530                 error "Ladvise failed with only -e argument"
21531
21532         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21533                 error "Ladvise failed with only -l argument"
21534
21535         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21536                 error "End offset should not be smaller than start offset"
21537
21538         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21539                 error "End offset should not be equal to start offset"
21540
21541         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21542                 error "Ladvise failed with overflowing -s argument"
21543
21544         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21545                 error "Ladvise failed with overflowing -e argument"
21546
21547         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21548                 error "Ladvise failed with overflowing -l argument"
21549
21550         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21551                 error "Ladvise succeeded with conflicting -l and -e arguments"
21552
21553         echo "Synchronous ladvise should wait"
21554         local delay=4
21555 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21556         do_nodes $(comma_list $(osts_nodes)) \
21557                 $LCTL set_param fail_val=$delay fail_loc=0x237
21558
21559         local start_ts=$SECONDS
21560         lfs ladvise -a willread $DIR/$tfile ||
21561                 error "Ladvise failed with no range argument"
21562         local end_ts=$SECONDS
21563         local inteval_ts=$((end_ts - start_ts))
21564
21565         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21566                 error "Synchronous advice didn't wait reply"
21567         fi
21568
21569         echo "Asynchronous ladvise shouldn't wait"
21570         local start_ts=$SECONDS
21571         lfs ladvise -a willread -b $DIR/$tfile ||
21572                 error "Ladvise failed with no range argument"
21573         local end_ts=$SECONDS
21574         local inteval_ts=$((end_ts - start_ts))
21575
21576         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21577                 error "Asynchronous advice blocked"
21578         fi
21579
21580         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21581         ladvise_willread_performance
21582 }
21583 run_test 255a "check 'lfs ladvise -a willread'"
21584
21585 facet_meminfo() {
21586         local facet=$1
21587         local info=$2
21588
21589         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21590 }
21591
21592 test_255b() {
21593         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21594                 skip "lustre < 2.8.54 does not support ladvise "
21595         remote_ost_nodsh && skip "remote OST with nodsh"
21596
21597         stack_trap "rm -f $DIR/$tfile"
21598         lfs setstripe -c 1 -i 0 $DIR/$tfile
21599
21600         ladvise_no_type dontneed $DIR/$tfile &&
21601                 skip "dontneed ladvise is not supported"
21602
21603         ladvise_no_ioctl $DIR/$tfile &&
21604                 skip "ladvise ioctl is not supported"
21605
21606         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21607                 [ "$ost1_FSTYPE" = "zfs" ] &&
21608                 skip "zfs-osd does not support 'ladvise dontneed'"
21609
21610         local size_mb=100
21611         local size=$((size_mb * 1048576))
21612         # In order to prevent disturbance of other processes, only check 3/4
21613         # of the memory usage
21614         local kibibytes=$((size_mb * 1024 * 3 / 4))
21615
21616         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21617                 error "dd to $DIR/$tfile failed"
21618
21619         #force write to complete before dropping OST cache & checking memory
21620         sync
21621
21622         local total=$(facet_meminfo ost1 MemTotal)
21623         echo "Total memory: $total KiB"
21624
21625         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21626         local before_read=$(facet_meminfo ost1 Cached)
21627         echo "Cache used before read: $before_read KiB"
21628
21629         lfs ladvise -a willread $DIR/$tfile ||
21630                 error "Ladvise willread failed"
21631         local after_read=$(facet_meminfo ost1 Cached)
21632         echo "Cache used after read: $after_read KiB"
21633
21634         lfs ladvise -a dontneed $DIR/$tfile ||
21635                 error "Ladvise dontneed again failed"
21636         local no_read=$(facet_meminfo ost1 Cached)
21637         echo "Cache used after dontneed ladvise: $no_read KiB"
21638
21639         if [ $total -lt $((before_read + kibibytes)) ]; then
21640                 echo "Memory is too small, abort checking"
21641                 return 0
21642         fi
21643
21644         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21645                 error "Ladvise willread should use more memory" \
21646                         "than $kibibytes KiB"
21647         fi
21648
21649         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21650                 error "Ladvise dontneed should release more memory" \
21651                         "than $kibibytes KiB"
21652         fi
21653 }
21654 run_test 255b "check 'lfs ladvise -a dontneed'"
21655
21656 test_255c() {
21657         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21658                 skip "lustre < 2.10.50 does not support lockahead"
21659
21660         local ost1_imp=$(get_osc_import_name client ost1)
21661         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21662                          cut -d'.' -f2)
21663         local count
21664         local new_count
21665         local difference
21666         local i
21667         local rc
21668
21669         test_mkdir -p $DIR/$tdir
21670         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21671
21672         #test 10 returns only success/failure
21673         i=10
21674         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21675         rc=$?
21676         if [ $rc -eq 255 ]; then
21677                 error "Ladvise test${i} failed, ${rc}"
21678         fi
21679
21680         #test 11 counts lock enqueue requests, all others count new locks
21681         i=11
21682         count=$(do_facet ost1 \
21683                 $LCTL get_param -n ost.OSS.ost.stats)
21684         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21685
21686         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21687         rc=$?
21688         if [ $rc -eq 255 ]; then
21689                 error "Ladvise test${i} failed, ${rc}"
21690         fi
21691
21692         new_count=$(do_facet ost1 \
21693                 $LCTL get_param -n ost.OSS.ost.stats)
21694         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21695                    awk '{ print $2 }')
21696
21697         difference="$((new_count - count))"
21698         if [ $difference -ne $rc ]; then
21699                 error "Ladvise test${i}, bad enqueue count, returned " \
21700                       "${rc}, actual ${difference}"
21701         fi
21702
21703         for i in $(seq 12 21); do
21704                 # If we do not do this, we run the risk of having too many
21705                 # locks and starting lock cancellation while we are checking
21706                 # lock counts.
21707                 cancel_lru_locks osc
21708
21709                 count=$($LCTL get_param -n \
21710                        ldlm.namespaces.$imp_name.lock_unused_count)
21711
21712                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21713                 rc=$?
21714                 if [ $rc -eq 255 ]; then
21715                         error "Ladvise test ${i} failed, ${rc}"
21716                 fi
21717
21718                 new_count=$($LCTL get_param -n \
21719                        ldlm.namespaces.$imp_name.lock_unused_count)
21720                 difference="$((new_count - count))"
21721
21722                 # Test 15 output is divided by 100 to map down to valid return
21723                 if [ $i -eq 15 ]; then
21724                         rc="$((rc * 100))"
21725                 fi
21726
21727                 if [ $difference -ne $rc ]; then
21728                         error "Ladvise test ${i}, bad lock count, returned " \
21729                               "${rc}, actual ${difference}"
21730                 fi
21731         done
21732
21733         #test 22 returns only success/failure
21734         i=22
21735         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21736         rc=$?
21737         if [ $rc -eq 255 ]; then
21738                 error "Ladvise test${i} failed, ${rc}"
21739         fi
21740 }
21741 run_test 255c "suite of ladvise lockahead tests"
21742
21743 test_256() {
21744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21745         remote_mds_nodsh && skip "remote MDS with nodsh"
21746         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21747         changelog_users $SINGLEMDS | grep "^cl" &&
21748                 skip "active changelog user"
21749
21750         local cl_user
21751         local cat_sl
21752         local mdt_dev
21753
21754         mdt_dev=$(mdsdevname 1)
21755         echo $mdt_dev
21756
21757         changelog_register || error "changelog_register failed"
21758
21759         rm -rf $DIR/$tdir
21760         mkdir_on_mdt0 $DIR/$tdir
21761
21762         changelog_clear 0 || error "changelog_clear failed"
21763
21764         # change something
21765         touch $DIR/$tdir/{1..10}
21766
21767         # stop the MDT
21768         stop $SINGLEMDS || error "Fail to stop MDT"
21769
21770         # remount the MDT
21771
21772         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21773
21774         #after mount new plainllog is used
21775         touch $DIR/$tdir/{11..19}
21776         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21777         stack_trap "rm -f $tmpfile"
21778         cat_sl=$(do_facet $SINGLEMDS "sync; \
21779                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21780                  llog_reader $tmpfile | grep -c type=1064553b")
21781         do_facet $SINGLEMDS llog_reader $tmpfile
21782
21783         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21784
21785         changelog_clear 0 || error "changelog_clear failed"
21786
21787         cat_sl=$(do_facet $SINGLEMDS "sync; \
21788                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21789                  llog_reader $tmpfile | grep -c type=1064553b")
21790
21791         if (( cat_sl == 2 )); then
21792                 error "Empty plain llog was not deleted from changelog catalog"
21793         elif (( cat_sl != 1 )); then
21794                 error "Active plain llog shouldn't be deleted from catalog"
21795         fi
21796 }
21797 run_test 256 "Check llog delete for empty and not full state"
21798
21799 test_257() {
21800         remote_mds_nodsh && skip "remote MDS with nodsh"
21801         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21802                 skip "Need MDS version at least 2.8.55"
21803
21804         test_mkdir $DIR/$tdir
21805
21806         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21807                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21808         stat $DIR/$tdir
21809
21810 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21811         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21812         local facet=mds$((mdtidx + 1))
21813         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21814         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21815
21816         stop $facet || error "stop MDS failed"
21817         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21818                 error "start MDS fail"
21819         wait_recovery_complete $facet
21820 }
21821 run_test 257 "xattr locks are not lost"
21822
21823 # Verify we take the i_mutex when security requires it
21824 test_258a() {
21825 #define OBD_FAIL_IMUTEX_SEC 0x141c
21826         $LCTL set_param fail_loc=0x141c
21827         touch $DIR/$tfile
21828         chmod u+s $DIR/$tfile
21829         chmod a+rwx $DIR/$tfile
21830         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21831         RC=$?
21832         if [ $RC -ne 0 ]; then
21833                 error "error, failed to take i_mutex, rc=$?"
21834         fi
21835         rm -f $DIR/$tfile
21836 }
21837 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21838
21839 # Verify we do NOT take the i_mutex in the normal case
21840 test_258b() {
21841 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21842         $LCTL set_param fail_loc=0x141d
21843         touch $DIR/$tfile
21844         chmod a+rwx $DIR
21845         chmod a+rw $DIR/$tfile
21846         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21847         RC=$?
21848         if [ $RC -ne 0 ]; then
21849                 error "error, took i_mutex unnecessarily, rc=$?"
21850         fi
21851         rm -f $DIR/$tfile
21852
21853 }
21854 run_test 258b "verify i_mutex security behavior"
21855
21856 test_259() {
21857         local file=$DIR/$tfile
21858         local before
21859         local after
21860
21861         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21862
21863         stack_trap "rm -f $file" EXIT
21864
21865         wait_delete_completed
21866         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21867         echo "before: $before"
21868
21869         $LFS setstripe -i 0 -c 1 $file
21870         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21871         sync_all_data
21872         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21873         echo "after write: $after"
21874
21875 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21876         do_facet ost1 $LCTL set_param fail_loc=0x2301
21877         $TRUNCATE $file 0
21878         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21879         echo "after truncate: $after"
21880
21881         stop ost1
21882         do_facet ost1 $LCTL set_param fail_loc=0
21883         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21884         sleep 2
21885         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21886         echo "after restart: $after"
21887         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21888                 error "missing truncate?"
21889
21890         return 0
21891 }
21892 run_test 259 "crash at delayed truncate"
21893
21894 test_260() {
21895 #define OBD_FAIL_MDC_CLOSE               0x806
21896         $LCTL set_param fail_loc=0x80000806
21897         touch $DIR/$tfile
21898
21899 }
21900 run_test 260 "Check mdc_close fail"
21901
21902 ### Data-on-MDT sanity tests ###
21903 test_270a() {
21904         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21905                 skip "Need MDS version at least 2.10.55 for DoM"
21906
21907         # create DoM file
21908         local dom=$DIR/$tdir/dom_file
21909         local tmp=$DIR/$tdir/tmp_file
21910
21911         mkdir_on_mdt0 $DIR/$tdir
21912
21913         # basic checks for DoM component creation
21914         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21915                 error "Can set MDT layout to non-first entry"
21916
21917         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21918                 error "Can define multiple entries as MDT layout"
21919
21920         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21921
21922         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21923         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21924         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21925
21926         local mdtidx=$($LFS getstripe -m $dom)
21927         local mdtname=MDT$(printf %04x $mdtidx)
21928         local facet=mds$((mdtidx + 1))
21929         local space_check=1
21930
21931         # Skip free space checks with ZFS
21932         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21933
21934         # write
21935         sync
21936         local size_tmp=$((65536 * 3))
21937         local mdtfree1=$(do_facet $facet \
21938                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21939
21940         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21941         # check also direct IO along write
21942         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21943         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21944         sync
21945         cmp $tmp $dom || error "file data is different"
21946         [ $(stat -c%s $dom) == $size_tmp ] ||
21947                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21948         if [ $space_check == 1 ]; then
21949                 local mdtfree2=$(do_facet $facet \
21950                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21951
21952                 # increase in usage from by $size_tmp
21953                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21954                         error "MDT free space wrong after write: " \
21955                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21956         fi
21957
21958         # truncate
21959         local size_dom=10000
21960
21961         $TRUNCATE $dom $size_dom
21962         [ $(stat -c%s $dom) == $size_dom ] ||
21963                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21964         if [ $space_check == 1 ]; then
21965                 mdtfree1=$(do_facet $facet \
21966                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21967                 # decrease in usage from $size_tmp to new $size_dom
21968                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21969                   $(((size_tmp - size_dom) / 1024)) ] ||
21970                         error "MDT free space is wrong after truncate: " \
21971                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21972         fi
21973
21974         # append
21975         cat $tmp >> $dom
21976         sync
21977         size_dom=$((size_dom + size_tmp))
21978         [ $(stat -c%s $dom) == $size_dom ] ||
21979                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21980         if [ $space_check == 1 ]; then
21981                 mdtfree2=$(do_facet $facet \
21982                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21983                 # increase in usage by $size_tmp from previous
21984                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21985                         error "MDT free space is wrong after append: " \
21986                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21987         fi
21988
21989         # delete
21990         rm $dom
21991         if [ $space_check == 1 ]; then
21992                 mdtfree1=$(do_facet $facet \
21993                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21994                 # decrease in usage by $size_dom from previous
21995                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21996                         error "MDT free space is wrong after removal: " \
21997                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21998         fi
21999
22000         # combined striping
22001         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22002                 error "Can't create DoM + OST striping"
22003
22004         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22005         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22006         # check also direct IO along write
22007         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22008         sync
22009         cmp $tmp $dom || error "file data is different"
22010         [ $(stat -c%s $dom) == $size_tmp ] ||
22011                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22012         rm $dom $tmp
22013
22014         return 0
22015 }
22016 run_test 270a "DoM: basic functionality tests"
22017
22018 test_270b() {
22019         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22020                 skip "Need MDS version at least 2.10.55"
22021
22022         local dom=$DIR/$tdir/dom_file
22023         local max_size=1048576
22024
22025         mkdir -p $DIR/$tdir
22026         $LFS setstripe -E $max_size -L mdt $dom
22027
22028         # truncate over the limit
22029         $TRUNCATE $dom $(($max_size + 1)) &&
22030                 error "successful truncate over the maximum size"
22031         # write over the limit
22032         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22033                 error "successful write over the maximum size"
22034         # append over the limit
22035         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22036         echo "12345" >> $dom && error "successful append over the maximum size"
22037         rm $dom
22038
22039         return 0
22040 }
22041 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22042
22043 test_270c() {
22044         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22045                 skip "Need MDS version at least 2.10.55"
22046
22047         mkdir -p $DIR/$tdir
22048         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22049
22050         # check files inherit DoM EA
22051         touch $DIR/$tdir/first
22052         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22053                 error "bad pattern"
22054         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22055                 error "bad stripe count"
22056         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22057                 error "bad stripe size"
22058
22059         # check directory inherits DoM EA and uses it as default
22060         mkdir $DIR/$tdir/subdir
22061         touch $DIR/$tdir/subdir/second
22062         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22063                 error "bad pattern in sub-directory"
22064         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22065                 error "bad stripe count in sub-directory"
22066         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22067                 error "bad stripe size in sub-directory"
22068         return 0
22069 }
22070 run_test 270c "DoM: DoM EA inheritance tests"
22071
22072 test_270d() {
22073         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22074                 skip "Need MDS version at least 2.10.55"
22075
22076         mkdir -p $DIR/$tdir
22077         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22078
22079         # inherit default DoM striping
22080         mkdir $DIR/$tdir/subdir
22081         touch $DIR/$tdir/subdir/f1
22082
22083         # change default directory striping
22084         $LFS setstripe -c 1 $DIR/$tdir/subdir
22085         touch $DIR/$tdir/subdir/f2
22086         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22087                 error "wrong default striping in file 2"
22088         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22089                 error "bad pattern in file 2"
22090         return 0
22091 }
22092 run_test 270d "DoM: change striping from DoM to RAID0"
22093
22094 test_270e() {
22095         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22096                 skip "Need MDS version at least 2.10.55"
22097
22098         mkdir -p $DIR/$tdir/dom
22099         mkdir -p $DIR/$tdir/norm
22100         DOMFILES=20
22101         NORMFILES=10
22102         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22103         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22104
22105         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22106         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22107
22108         # find DoM files by layout
22109         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22110         [ $NUM -eq  $DOMFILES ] ||
22111                 error "lfs find -L: found $NUM, expected $DOMFILES"
22112         echo "Test 1: lfs find 20 DOM files by layout: OK"
22113
22114         # there should be 1 dir with default DOM striping
22115         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22116         [ $NUM -eq  1 ] ||
22117                 error "lfs find -L: found $NUM, expected 1 dir"
22118         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22119
22120         # find DoM files by stripe size
22121         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22122         [ $NUM -eq  $DOMFILES ] ||
22123                 error "lfs find -S: found $NUM, expected $DOMFILES"
22124         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22125
22126         # find files by stripe offset except DoM files
22127         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22128         [ $NUM -eq  $NORMFILES ] ||
22129                 error "lfs find -i: found $NUM, expected $NORMFILES"
22130         echo "Test 5: lfs find no DOM files by stripe index: OK"
22131         return 0
22132 }
22133 run_test 270e "DoM: lfs find with DoM files test"
22134
22135 test_270f() {
22136         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22137                 skip "Need MDS version at least 2.10.55"
22138
22139         local mdtname=${FSNAME}-MDT0000-mdtlov
22140         local dom=$DIR/$tdir/dom_file
22141         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22142                                                 lod.$mdtname.dom_stripesize)
22143         local dom_limit=131072
22144
22145         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22146         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22147                                                 lod.$mdtname.dom_stripesize)
22148         [ ${dom_limit} -eq ${dom_current} ] ||
22149                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22150
22151         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22152         $LFS setstripe -d $DIR/$tdir
22153         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22154                 error "Can't set directory default striping"
22155
22156         # exceed maximum stripe size
22157         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22158                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22159         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22160                 error "Able to create DoM component size more than LOD limit"
22161
22162         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22163         dom_current=$(do_facet mds1 $LCTL get_param -n \
22164                                                 lod.$mdtname.dom_stripesize)
22165         [ 0 -eq ${dom_current} ] ||
22166                 error "Can't set zero DoM stripe limit"
22167         rm $dom
22168
22169         # attempt to create DoM file on server with disabled DoM should
22170         # remove DoM entry from layout and be succeed
22171         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22172                 error "Can't create DoM file (DoM is disabled)"
22173         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22174                 error "File has DoM component while DoM is disabled"
22175         rm $dom
22176
22177         # attempt to create DoM file with only DoM stripe should return error
22178         $LFS setstripe -E $dom_limit -L mdt $dom &&
22179                 error "Able to create DoM-only file while DoM is disabled"
22180
22181         # too low values to be aligned with smallest stripe size 64K
22182         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22183         dom_current=$(do_facet mds1 $LCTL get_param -n \
22184                                                 lod.$mdtname.dom_stripesize)
22185         [ 30000 -eq ${dom_current} ] &&
22186                 error "Can set too small DoM stripe limit"
22187
22188         # 64K is a minimal stripe size in Lustre, expect limit of that size
22189         [ 65536 -eq ${dom_current} ] ||
22190                 error "Limit is not set to 64K but ${dom_current}"
22191
22192         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22193         dom_current=$(do_facet mds1 $LCTL get_param -n \
22194                                                 lod.$mdtname.dom_stripesize)
22195         echo $dom_current
22196         [ 2147483648 -eq ${dom_current} ] &&
22197                 error "Can set too large DoM stripe limit"
22198
22199         do_facet mds1 $LCTL set_param -n \
22200                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22201         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22202                 error "Can't create DoM component size after limit change"
22203         do_facet mds1 $LCTL set_param -n \
22204                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22205         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22206                 error "Can't create DoM file after limit decrease"
22207         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22208                 error "Can create big DoM component after limit decrease"
22209         touch ${dom}_def ||
22210                 error "Can't create file with old default layout"
22211
22212         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22213         return 0
22214 }
22215 run_test 270f "DoM: maximum DoM stripe size checks"
22216
22217 test_270g() {
22218         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22219                 skip "Need MDS version at least 2.13.52"
22220         local dom=$DIR/$tdir/$tfile
22221
22222         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22223         local lodname=${FSNAME}-MDT0000-mdtlov
22224
22225         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22226         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22227         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22228         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22229
22230         local dom_limit=1024
22231         local dom_threshold="50%"
22232
22233         $LFS setstripe -d $DIR/$tdir
22234         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22235                 error "Can't set directory default striping"
22236
22237         do_facet mds1 $LCTL set_param -n \
22238                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22239         # set 0 threshold and create DOM file to change tunable stripesize
22240         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22241         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22242                 error "Failed to create $dom file"
22243         # now tunable dom_cur_stripesize should reach maximum
22244         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22245                                         lod.${lodname}.dom_stripesize_cur_kb)
22246         [[ $dom_current == $dom_limit ]] ||
22247                 error "Current DOM stripesize is not maximum"
22248         rm $dom
22249
22250         # set threshold for further tests
22251         do_facet mds1 $LCTL set_param -n \
22252                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22253         echo "DOM threshold is $dom_threshold free space"
22254         local dom_def
22255         local dom_set
22256         # Spoof bfree to exceed threshold
22257         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22258         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22259         for spfree in 40 20 0 15 30 55; do
22260                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22261                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22262                         error "Failed to create $dom file"
22263                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22264                                         lod.${lodname}.dom_stripesize_cur_kb)
22265                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22266                 [[ $dom_def != $dom_current ]] ||
22267                         error "Default stripe size was not changed"
22268                 if [[ $spfree > 0 ]] ; then
22269                         dom_set=$($LFS getstripe -S $dom)
22270                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22271                                 error "DOM component size is still old"
22272                 else
22273                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22274                                 error "DoM component is set with no free space"
22275                 fi
22276                 rm $dom
22277                 dom_current=$dom_def
22278         done
22279 }
22280 run_test 270g "DoM: default DoM stripe size depends on free space"
22281
22282 test_270h() {
22283         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22284                 skip "Need MDS version at least 2.13.53"
22285
22286         local mdtname=${FSNAME}-MDT0000-mdtlov
22287         local dom=$DIR/$tdir/$tfile
22288         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22289
22290         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22291         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22292
22293         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22294         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22295                 error "can't create OST file"
22296         # mirrored file with DOM entry in the second mirror
22297         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22298                 error "can't create mirror with DoM component"
22299
22300         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22301
22302         # DOM component in the middle and has other enries in the same mirror,
22303         # should succeed but lost DoM component
22304         $LFS setstripe --copy=${dom}_1 $dom ||
22305                 error "Can't create file from OST|DOM mirror layout"
22306         # check new file has no DoM layout after all
22307         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22308                 error "File has DoM component while DoM is disabled"
22309 }
22310 run_test 270h "DoM: DoM stripe removal when disabled on server"
22311
22312 test_270i() {
22313         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22314                 skip "Need MDS version at least 2.14.54"
22315
22316         mkdir $DIR/$tdir
22317         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22318                 error "setstripe should fail" || true
22319 }
22320 run_test 270i "DoM: setting invalid DoM striping should fail"
22321
22322 test_271a() {
22323         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22324                 skip "Need MDS version at least 2.10.55"
22325
22326         local dom=$DIR/$tdir/dom
22327
22328         mkdir -p $DIR/$tdir
22329
22330         $LFS setstripe -E 1024K -L mdt $dom
22331
22332         lctl set_param -n mdc.*.stats=clear
22333         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22334         cat $dom > /dev/null
22335         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22336         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22337         ls $dom
22338         rm -f $dom
22339 }
22340 run_test 271a "DoM: data is cached for read after write"
22341
22342 test_271b() {
22343         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22344                 skip "Need MDS version at least 2.10.55"
22345
22346         local dom=$DIR/$tdir/dom
22347
22348         mkdir -p $DIR/$tdir
22349
22350         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22351
22352         lctl set_param -n mdc.*.stats=clear
22353         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22354         cancel_lru_locks mdc
22355         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22356         # second stat to check size is cached on client
22357         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22358         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22359         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22360         rm -f $dom
22361 }
22362 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22363
22364 test_271ba() {
22365         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22366                 skip "Need MDS version at least 2.10.55"
22367
22368         local dom=$DIR/$tdir/dom
22369
22370         mkdir -p $DIR/$tdir
22371
22372         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22373
22374         lctl set_param -n mdc.*.stats=clear
22375         lctl set_param -n osc.*.stats=clear
22376         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22377         cancel_lru_locks mdc
22378         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22379         # second stat to check size is cached on client
22380         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22381         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22382         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22383         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22384         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22385         rm -f $dom
22386 }
22387 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22388
22389
22390 get_mdc_stats() {
22391         local mdtidx=$1
22392         local param=$2
22393         local mdt=MDT$(printf %04x $mdtidx)
22394
22395         if [ -z $param ]; then
22396                 lctl get_param -n mdc.*$mdt*.stats
22397         else
22398                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22399         fi
22400 }
22401
22402 test_271c() {
22403         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22404                 skip "Need MDS version at least 2.10.55"
22405
22406         local dom=$DIR/$tdir/dom
22407
22408         mkdir -p $DIR/$tdir
22409
22410         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22411
22412         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22413         local facet=mds$((mdtidx + 1))
22414
22415         cancel_lru_locks mdc
22416         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22417         createmany -o $dom 1000
22418         lctl set_param -n mdc.*.stats=clear
22419         smalliomany -w $dom 1000 200
22420         get_mdc_stats $mdtidx
22421         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22422         # Each file has 1 open, 1 IO enqueues, total 2000
22423         # but now we have also +1 getxattr for security.capability, total 3000
22424         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22425         unlinkmany $dom 1000
22426
22427         cancel_lru_locks mdc
22428         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22429         createmany -o $dom 1000
22430         lctl set_param -n mdc.*.stats=clear
22431         smalliomany -w $dom 1000 200
22432         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22433         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22434         # for OPEN and IO lock.
22435         [ $((enq - enq_2)) -ge 1000 ] ||
22436                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22437         unlinkmany $dom 1000
22438         return 0
22439 }
22440 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22441
22442 cleanup_271def_tests() {
22443         trap 0
22444         rm -f $1
22445 }
22446
22447 test_271d() {
22448         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22449                 skip "Need MDS version at least 2.10.57"
22450
22451         local dom=$DIR/$tdir/dom
22452         local tmp=$TMP/$tfile
22453         trap "cleanup_271def_tests $tmp" EXIT
22454
22455         mkdir -p $DIR/$tdir
22456
22457         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22458
22459         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22460
22461         cancel_lru_locks mdc
22462         dd if=/dev/urandom of=$tmp bs=1000 count=1
22463         dd if=$tmp of=$dom bs=1000 count=1
22464         cancel_lru_locks mdc
22465
22466         cat /etc/hosts >> $tmp
22467         lctl set_param -n mdc.*.stats=clear
22468
22469         # append data to the same file it should update local page
22470         echo "Append to the same page"
22471         cat /etc/hosts >> $dom
22472         local num=$(get_mdc_stats $mdtidx ost_read)
22473         local ra=$(get_mdc_stats $mdtidx req_active)
22474         local rw=$(get_mdc_stats $mdtidx req_waittime)
22475
22476         [ -z $num ] || error "$num READ RPC occured"
22477         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22478         echo "... DONE"
22479
22480         # compare content
22481         cmp $tmp $dom || error "file miscompare"
22482
22483         cancel_lru_locks mdc
22484         lctl set_param -n mdc.*.stats=clear
22485
22486         echo "Open and read file"
22487         cat $dom > /dev/null
22488         local num=$(get_mdc_stats $mdtidx ost_read)
22489         local ra=$(get_mdc_stats $mdtidx req_active)
22490         local rw=$(get_mdc_stats $mdtidx req_waittime)
22491
22492         [ -z $num ] || error "$num READ RPC occured"
22493         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22494         echo "... DONE"
22495
22496         # compare content
22497         cmp $tmp $dom || error "file miscompare"
22498
22499         return 0
22500 }
22501 run_test 271d "DoM: read on open (1K file in reply buffer)"
22502
22503 test_271f() {
22504         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22505                 skip "Need MDS version at least 2.10.57"
22506
22507         local dom=$DIR/$tdir/dom
22508         local tmp=$TMP/$tfile
22509         trap "cleanup_271def_tests $tmp" EXIT
22510
22511         mkdir -p $DIR/$tdir
22512
22513         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22514
22515         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22516
22517         cancel_lru_locks mdc
22518         dd if=/dev/urandom of=$tmp bs=265000 count=1
22519         dd if=$tmp of=$dom bs=265000 count=1
22520         cancel_lru_locks mdc
22521         cat /etc/hosts >> $tmp
22522         lctl set_param -n mdc.*.stats=clear
22523
22524         echo "Append to the same page"
22525         cat /etc/hosts >> $dom
22526         local num=$(get_mdc_stats $mdtidx ost_read)
22527         local ra=$(get_mdc_stats $mdtidx req_active)
22528         local rw=$(get_mdc_stats $mdtidx req_waittime)
22529
22530         [ -z $num ] || error "$num READ RPC occured"
22531         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22532         echo "... DONE"
22533
22534         # compare content
22535         cmp $tmp $dom || error "file miscompare"
22536
22537         cancel_lru_locks mdc
22538         lctl set_param -n mdc.*.stats=clear
22539
22540         echo "Open and read file"
22541         cat $dom > /dev/null
22542         local num=$(get_mdc_stats $mdtidx ost_read)
22543         local ra=$(get_mdc_stats $mdtidx req_active)
22544         local rw=$(get_mdc_stats $mdtidx req_waittime)
22545
22546         [ -z $num ] && num=0
22547         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22548         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22549         echo "... DONE"
22550
22551         # compare content
22552         cmp $tmp $dom || error "file miscompare"
22553
22554         return 0
22555 }
22556 run_test 271f "DoM: read on open (200K file and read tail)"
22557
22558 test_271g() {
22559         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22560                 skip "Skipping due to old client or server version"
22561
22562         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22563         # to get layout
22564         $CHECKSTAT -t file $DIR1/$tfile
22565
22566         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22567         MULTIOP_PID=$!
22568         sleep 1
22569         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22570         $LCTL set_param fail_loc=0x80000314
22571         rm $DIR1/$tfile || error "Unlink fails"
22572         RC=$?
22573         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22574         [ $RC -eq 0 ] || error "Failed write to stale object"
22575 }
22576 run_test 271g "Discard DoM data vs client flush race"
22577
22578 test_272a() {
22579         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22580                 skip "Need MDS version at least 2.11.50"
22581
22582         local dom=$DIR/$tdir/dom
22583         mkdir -p $DIR/$tdir
22584
22585         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22586         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22587                 error "failed to write data into $dom"
22588         local old_md5=$(md5sum $dom)
22589
22590         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22591                 error "failed to migrate to the same DoM component"
22592
22593         local new_md5=$(md5sum $dom)
22594
22595         [ "$old_md5" == "$new_md5" ] ||
22596                 error "md5sum differ: $old_md5, $new_md5"
22597
22598         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22599                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22600 }
22601 run_test 272a "DoM migration: new layout with the same DOM component"
22602
22603 test_272b() {
22604         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22605                 skip "Need MDS version at least 2.11.50"
22606
22607         local dom=$DIR/$tdir/dom
22608         mkdir -p $DIR/$tdir
22609         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22610
22611         local mdtidx=$($LFS getstripe -m $dom)
22612         local mdtname=MDT$(printf %04x $mdtidx)
22613         local facet=mds$((mdtidx + 1))
22614
22615         local mdtfree1=$(do_facet $facet \
22616                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22617         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22618                 error "failed to write data into $dom"
22619         local old_md5=$(md5sum $dom)
22620         cancel_lru_locks mdc
22621         local mdtfree1=$(do_facet $facet \
22622                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22623
22624         $LFS migrate -c2 $dom ||
22625                 error "failed to migrate to the new composite layout"
22626         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22627                 error "MDT stripe was not removed"
22628
22629         cancel_lru_locks mdc
22630         local new_md5=$(md5sum $dom)
22631         [ "$old_md5" == "$new_md5" ] ||
22632                 error "$old_md5 != $new_md5"
22633
22634         # Skip free space checks with ZFS
22635         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22636                 local mdtfree2=$(do_facet $facet \
22637                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22638                 [ $mdtfree2 -gt $mdtfree1 ] ||
22639                         error "MDT space is not freed after migration"
22640         fi
22641         return 0
22642 }
22643 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22644
22645 test_272c() {
22646         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22647                 skip "Need MDS version at least 2.11.50"
22648
22649         local dom=$DIR/$tdir/$tfile
22650         mkdir -p $DIR/$tdir
22651         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22652
22653         local mdtidx=$($LFS getstripe -m $dom)
22654         local mdtname=MDT$(printf %04x $mdtidx)
22655         local facet=mds$((mdtidx + 1))
22656
22657         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22658                 error "failed to write data into $dom"
22659         local old_md5=$(md5sum $dom)
22660         cancel_lru_locks mdc
22661         local mdtfree1=$(do_facet $facet \
22662                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22663
22664         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22665                 error "failed to migrate to the new composite layout"
22666         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22667                 error "MDT stripe was not removed"
22668
22669         cancel_lru_locks mdc
22670         local new_md5=$(md5sum $dom)
22671         [ "$old_md5" == "$new_md5" ] ||
22672                 error "$old_md5 != $new_md5"
22673
22674         # Skip free space checks with ZFS
22675         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22676                 local mdtfree2=$(do_facet $facet \
22677                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22678                 [ $mdtfree2 -gt $mdtfree1 ] ||
22679                         error "MDS space is not freed after migration"
22680         fi
22681         return 0
22682 }
22683 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22684
22685 test_272d() {
22686         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22687                 skip "Need MDS version at least 2.12.55"
22688
22689         local dom=$DIR/$tdir/$tfile
22690         mkdir -p $DIR/$tdir
22691         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22692
22693         local mdtidx=$($LFS getstripe -m $dom)
22694         local mdtname=MDT$(printf %04x $mdtidx)
22695         local facet=mds$((mdtidx + 1))
22696
22697         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22698                 error "failed to write data into $dom"
22699         local old_md5=$(md5sum $dom)
22700         cancel_lru_locks mdc
22701         local mdtfree1=$(do_facet $facet \
22702                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22703
22704         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22705                 error "failed mirroring to the new composite layout"
22706         $LFS mirror resync $dom ||
22707                 error "failed mirror resync"
22708         $LFS mirror split --mirror-id 1 -d $dom ||
22709                 error "failed mirror split"
22710
22711         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22712                 error "MDT stripe was not removed"
22713
22714         cancel_lru_locks mdc
22715         local new_md5=$(md5sum $dom)
22716         [ "$old_md5" == "$new_md5" ] ||
22717                 error "$old_md5 != $new_md5"
22718
22719         # Skip free space checks with ZFS
22720         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22721                 local mdtfree2=$(do_facet $facet \
22722                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22723                 [ $mdtfree2 -gt $mdtfree1 ] ||
22724                         error "MDS space is not freed after DOM mirror deletion"
22725         fi
22726         return 0
22727 }
22728 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22729
22730 test_272e() {
22731         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22732                 skip "Need MDS version at least 2.12.55"
22733
22734         local dom=$DIR/$tdir/$tfile
22735         mkdir -p $DIR/$tdir
22736         $LFS setstripe -c 2 $dom
22737
22738         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22739                 error "failed to write data into $dom"
22740         local old_md5=$(md5sum $dom)
22741         cancel_lru_locks
22742
22743         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22744                 error "failed mirroring to the DOM layout"
22745         $LFS mirror resync $dom ||
22746                 error "failed mirror resync"
22747         $LFS mirror split --mirror-id 1 -d $dom ||
22748                 error "failed mirror split"
22749
22750         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22751                 error "MDT stripe wasn't set"
22752
22753         cancel_lru_locks
22754         local new_md5=$(md5sum $dom)
22755         [ "$old_md5" == "$new_md5" ] ||
22756                 error "$old_md5 != $new_md5"
22757
22758         return 0
22759 }
22760 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22761
22762 test_272f() {
22763         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22764                 skip "Need MDS version at least 2.12.55"
22765
22766         local dom=$DIR/$tdir/$tfile
22767         mkdir -p $DIR/$tdir
22768         $LFS setstripe -c 2 $dom
22769
22770         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22771                 error "failed to write data into $dom"
22772         local old_md5=$(md5sum $dom)
22773         cancel_lru_locks
22774
22775         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22776                 error "failed migrating to the DOM file"
22777
22778         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22779                 error "MDT stripe wasn't set"
22780
22781         cancel_lru_locks
22782         local new_md5=$(md5sum $dom)
22783         [ "$old_md5" != "$new_md5" ] &&
22784                 error "$old_md5 != $new_md5"
22785
22786         return 0
22787 }
22788 run_test 272f "DoM migration: OST-striped file to DOM file"
22789
22790 test_273a() {
22791         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22792                 skip "Need MDS version at least 2.11.50"
22793
22794         # Layout swap cannot be done if either file has DOM component,
22795         # this will never be supported, migration should be used instead
22796
22797         local dom=$DIR/$tdir/$tfile
22798         mkdir -p $DIR/$tdir
22799
22800         $LFS setstripe -c2 ${dom}_plain
22801         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22802         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22803                 error "can swap layout with DoM component"
22804         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22805                 error "can swap layout with DoM component"
22806
22807         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22808         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22809                 error "can swap layout with DoM component"
22810         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22811                 error "can swap layout with DoM component"
22812         return 0
22813 }
22814 run_test 273a "DoM: layout swapping should fail with DOM"
22815
22816 test_273b() {
22817         mkdir -p $DIR/$tdir
22818         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22819
22820 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22821         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22822
22823         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22824 }
22825 run_test 273b "DoM: race writeback and object destroy"
22826
22827 test_275() {
22828         remote_ost_nodsh && skip "remote OST with nodsh"
22829         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22830                 skip "Need OST version >= 2.10.57"
22831
22832         local file=$DIR/$tfile
22833         local oss
22834
22835         oss=$(comma_list $(osts_nodes))
22836
22837         dd if=/dev/urandom of=$file bs=1M count=2 ||
22838                 error "failed to create a file"
22839         cancel_lru_locks osc
22840
22841         #lock 1
22842         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22843                 error "failed to read a file"
22844
22845 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22846         $LCTL set_param fail_loc=0x8000031f
22847
22848         cancel_lru_locks osc &
22849         sleep 1
22850
22851 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22852         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22853         #IO takes another lock, but matches the PENDING one
22854         #and places it to the IO RPC
22855         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22856                 error "failed to read a file with PENDING lock"
22857 }
22858 run_test 275 "Read on a canceled duplicate lock"
22859
22860 test_276() {
22861         remote_ost_nodsh && skip "remote OST with nodsh"
22862         local pid
22863
22864         do_facet ost1 "(while true; do \
22865                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22866                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22867         pid=$!
22868
22869         for LOOP in $(seq 20); do
22870                 stop ost1
22871                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22872         done
22873         kill -9 $pid
22874         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22875                 rm $TMP/sanity_276_pid"
22876 }
22877 run_test 276 "Race between mount and obd_statfs"
22878
22879 test_277() {
22880         $LCTL set_param ldlm.namespaces.*.lru_size=0
22881         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22882         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22883                         grep ^used_mb | awk '{print $2}')
22884         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22885         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22886                 oflag=direct conv=notrunc
22887         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22888                         grep ^used_mb | awk '{print $2}')
22889         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22890 }
22891 run_test 277 "Direct IO shall drop page cache"
22892
22893 test_278() {
22894         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22895         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22896         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22897                 skip "needs the same host for mdt1 mdt2" && return
22898
22899         local pid1
22900         local pid2
22901
22902 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22903         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22904         stop mds2 &
22905         pid2=$!
22906
22907         stop mds1
22908
22909         echo "Starting MDTs"
22910         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22911         wait $pid2
22912 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22913 #will return NULL
22914         do_facet mds2 $LCTL set_param fail_loc=0
22915
22916         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22917         wait_recovery_complete mds2
22918 }
22919 run_test 278 "Race starting MDS between MDTs stop/start"
22920
22921 test_280() {
22922         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22923                 skip "Need MGS version at least 2.13.52"
22924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22925         combined_mgs_mds || skip "needs combined MGS/MDT"
22926
22927         umount_client $MOUNT
22928 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22929         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22930
22931         mount_client $MOUNT &
22932         sleep 1
22933         stop mgs || error "stop mgs failed"
22934         #for a race mgs would crash
22935         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22936         # make sure we unmount client before remounting
22937         wait
22938         umount_client $MOUNT
22939         mount_client $MOUNT || error "mount client failed"
22940 }
22941 run_test 280 "Race between MGS umount and client llog processing"
22942
22943 cleanup_test_300() {
22944         trap 0
22945         umask $SAVE_UMASK
22946 }
22947 test_striped_dir() {
22948         local mdt_index=$1
22949         local stripe_count
22950         local stripe_index
22951
22952         mkdir -p $DIR/$tdir
22953
22954         SAVE_UMASK=$(umask)
22955         trap cleanup_test_300 RETURN EXIT
22956
22957         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22958                                                 $DIR/$tdir/striped_dir ||
22959                 error "set striped dir error"
22960
22961         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22962         [ "$mode" = "755" ] || error "expect 755 got $mode"
22963
22964         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22965                 error "getdirstripe failed"
22966         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22967         if [ "$stripe_count" != "2" ]; then
22968                 error "1:stripe_count is $stripe_count, expect 2"
22969         fi
22970         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22971         if [ "$stripe_count" != "2" ]; then
22972                 error "2:stripe_count is $stripe_count, expect 2"
22973         fi
22974
22975         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22976         if [ "$stripe_index" != "$mdt_index" ]; then
22977                 error "stripe_index is $stripe_index, expect $mdt_index"
22978         fi
22979
22980         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22981                 error "nlink error after create striped dir"
22982
22983         mkdir $DIR/$tdir/striped_dir/a
22984         mkdir $DIR/$tdir/striped_dir/b
22985
22986         stat $DIR/$tdir/striped_dir/a ||
22987                 error "create dir under striped dir failed"
22988         stat $DIR/$tdir/striped_dir/b ||
22989                 error "create dir under striped dir failed"
22990
22991         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22992                 error "nlink error after mkdir"
22993
22994         rmdir $DIR/$tdir/striped_dir/a
22995         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22996                 error "nlink error after rmdir"
22997
22998         rmdir $DIR/$tdir/striped_dir/b
22999         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23000                 error "nlink error after rmdir"
23001
23002         chattr +i $DIR/$tdir/striped_dir
23003         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23004                 error "immutable flags not working under striped dir!"
23005         chattr -i $DIR/$tdir/striped_dir
23006
23007         rmdir $DIR/$tdir/striped_dir ||
23008                 error "rmdir striped dir error"
23009
23010         cleanup_test_300
23011
23012         true
23013 }
23014
23015 test_300a() {
23016         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23017                 skip "skipped for lustre < 2.7.0"
23018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23020
23021         test_striped_dir 0 || error "failed on striped dir on MDT0"
23022         test_striped_dir 1 || error "failed on striped dir on MDT0"
23023 }
23024 run_test 300a "basic striped dir sanity test"
23025
23026 test_300b() {
23027         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23028                 skip "skipped for lustre < 2.7.0"
23029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23030         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23031
23032         local i
23033         local mtime1
23034         local mtime2
23035         local mtime3
23036
23037         test_mkdir $DIR/$tdir || error "mkdir fail"
23038         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23039                 error "set striped dir error"
23040         for i in {0..9}; do
23041                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23042                 sleep 1
23043                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23044                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23045                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23046                 sleep 1
23047                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23048                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23049                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23050         done
23051         true
23052 }
23053 run_test 300b "check ctime/mtime for striped dir"
23054
23055 test_300c() {
23056         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23057                 skip "skipped for lustre < 2.7.0"
23058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23059         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23060
23061         local file_count
23062
23063         mkdir_on_mdt0 $DIR/$tdir
23064         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23065                 error "set striped dir error"
23066
23067         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23068                 error "chown striped dir failed"
23069
23070         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23071                 error "create 5k files failed"
23072
23073         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23074
23075         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23076
23077         rm -rf $DIR/$tdir
23078 }
23079 run_test 300c "chown && check ls under striped directory"
23080
23081 test_300d() {
23082         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23083                 skip "skipped for lustre < 2.7.0"
23084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23085         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23086
23087         local stripe_count
23088         local file
23089
23090         mkdir -p $DIR/$tdir
23091         $LFS setstripe -c 2 $DIR/$tdir
23092
23093         #local striped directory
23094         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23095                 error "set striped dir error"
23096         #look at the directories for debug purposes
23097         ls -l $DIR/$tdir
23098         $LFS getdirstripe $DIR/$tdir
23099         ls -l $DIR/$tdir/striped_dir
23100         $LFS getdirstripe $DIR/$tdir/striped_dir
23101         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23102                 error "create 10 files failed"
23103
23104         #remote striped directory
23105         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23106                 error "set striped dir error"
23107         #look at the directories for debug purposes
23108         ls -l $DIR/$tdir
23109         $LFS getdirstripe $DIR/$tdir
23110         ls -l $DIR/$tdir/remote_striped_dir
23111         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23112         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23113                 error "create 10 files failed"
23114
23115         for file in $(find $DIR/$tdir); do
23116                 stripe_count=$($LFS getstripe -c $file)
23117                 [ $stripe_count -eq 2 ] ||
23118                         error "wrong stripe $stripe_count for $file"
23119         done
23120
23121         rm -rf $DIR/$tdir
23122 }
23123 run_test 300d "check default stripe under striped directory"
23124
23125 test_300e() {
23126         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23127                 skip "Need MDS version at least 2.7.55"
23128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23129         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23130
23131         local stripe_count
23132         local file
23133
23134         mkdir -p $DIR/$tdir
23135
23136         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23137                 error "set striped dir error"
23138
23139         touch $DIR/$tdir/striped_dir/a
23140         touch $DIR/$tdir/striped_dir/b
23141         touch $DIR/$tdir/striped_dir/c
23142
23143         mkdir $DIR/$tdir/striped_dir/dir_a
23144         mkdir $DIR/$tdir/striped_dir/dir_b
23145         mkdir $DIR/$tdir/striped_dir/dir_c
23146
23147         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23148                 error "set striped adir under striped dir error"
23149
23150         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23151                 error "set striped bdir under striped dir error"
23152
23153         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23154                 error "set striped cdir under striped dir error"
23155
23156         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23157                 error "rename dir under striped dir fails"
23158
23159         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23160                 error "rename dir under different stripes fails"
23161
23162         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23163                 error "rename file under striped dir should succeed"
23164
23165         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23166                 error "rename dir under striped dir should succeed"
23167
23168         rm -rf $DIR/$tdir
23169 }
23170 run_test 300e "check rename under striped directory"
23171
23172 test_300f() {
23173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23175         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23176                 skip "Need MDS version at least 2.7.55"
23177
23178         local stripe_count
23179         local file
23180
23181         rm -rf $DIR/$tdir
23182         mkdir -p $DIR/$tdir
23183
23184         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23185                 error "set striped dir error"
23186
23187         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23188                 error "set striped dir error"
23189
23190         touch $DIR/$tdir/striped_dir/a
23191         mkdir $DIR/$tdir/striped_dir/dir_a
23192         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23193                 error "create striped dir under striped dir fails"
23194
23195         touch $DIR/$tdir/striped_dir1/b
23196         mkdir $DIR/$tdir/striped_dir1/dir_b
23197         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23198                 error "create striped dir under striped dir fails"
23199
23200         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23201                 error "rename dir under different striped dir should fail"
23202
23203         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23204                 error "rename striped dir under diff striped dir should fail"
23205
23206         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23207                 error "rename file under diff striped dirs fails"
23208
23209         rm -rf $DIR/$tdir
23210 }
23211 run_test 300f "check rename cross striped directory"
23212
23213 test_300_check_default_striped_dir()
23214 {
23215         local dirname=$1
23216         local default_count=$2
23217         local default_index=$3
23218         local stripe_count
23219         local stripe_index
23220         local dir_stripe_index
23221         local dir
23222
23223         echo "checking $dirname $default_count $default_index"
23224         $LFS setdirstripe -D -c $default_count -i $default_index \
23225                                 -H all_char $DIR/$tdir/$dirname ||
23226                 error "set default stripe on striped dir error"
23227         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23228         [ $stripe_count -eq $default_count ] ||
23229                 error "expect $default_count get $stripe_count for $dirname"
23230
23231         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23232         [ $stripe_index -eq $default_index ] ||
23233                 error "expect $default_index get $stripe_index for $dirname"
23234
23235         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23236                                                 error "create dirs failed"
23237
23238         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23239         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23240         for dir in $(find $DIR/$tdir/$dirname/*); do
23241                 stripe_count=$($LFS getdirstripe -c $dir)
23242                 (( $stripe_count == $default_count )) ||
23243                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23244                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23245                 error "stripe count $default_count != $stripe_count for $dir"
23246
23247                 stripe_index=$($LFS getdirstripe -i $dir)
23248                 [ $default_index -eq -1 ] ||
23249                         [ $stripe_index -eq $default_index ] ||
23250                         error "$stripe_index != $default_index for $dir"
23251
23252                 #check default stripe
23253                 stripe_count=$($LFS getdirstripe -D -c $dir)
23254                 [ $stripe_count -eq $default_count ] ||
23255                 error "default count $default_count != $stripe_count for $dir"
23256
23257                 stripe_index=$($LFS getdirstripe -D -i $dir)
23258                 [ $stripe_index -eq $default_index ] ||
23259                 error "default index $default_index != $stripe_index for $dir"
23260         done
23261         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23262 }
23263
23264 test_300g() {
23265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23266         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23267                 skip "Need MDS version at least 2.7.55"
23268
23269         local dir
23270         local stripe_count
23271         local stripe_index
23272
23273         mkdir_on_mdt0 $DIR/$tdir
23274         mkdir $DIR/$tdir/normal_dir
23275
23276         #Checking when client cache stripe index
23277         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23278         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23279                 error "create striped_dir failed"
23280
23281         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23282                 error "create dir0 fails"
23283         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23284         [ $stripe_index -eq 0 ] ||
23285                 error "dir0 expect index 0 got $stripe_index"
23286
23287         mkdir $DIR/$tdir/striped_dir/dir1 ||
23288                 error "create dir1 fails"
23289         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23290         [ $stripe_index -eq 1 ] ||
23291                 error "dir1 expect index 1 got $stripe_index"
23292
23293         #check default stripe count/stripe index
23294         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23295         test_300_check_default_striped_dir normal_dir 1 0
23296         test_300_check_default_striped_dir normal_dir -1 1
23297         test_300_check_default_striped_dir normal_dir 2 -1
23298
23299         #delete default stripe information
23300         echo "delete default stripeEA"
23301         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23302                 error "set default stripe on striped dir error"
23303
23304         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23305         for dir in $(find $DIR/$tdir/normal_dir/*); do
23306                 stripe_count=$($LFS getdirstripe -c $dir)
23307                 [ $stripe_count -eq 0 ] ||
23308                         error "expect 1 get $stripe_count for $dir"
23309         done
23310 }
23311 run_test 300g "check default striped directory for normal directory"
23312
23313 test_300h() {
23314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23315         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23316                 skip "Need MDS version at least 2.7.55"
23317
23318         local dir
23319         local stripe_count
23320
23321         mkdir $DIR/$tdir
23322         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23323                 error "set striped dir error"
23324
23325         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23326         test_300_check_default_striped_dir striped_dir 1 0
23327         test_300_check_default_striped_dir striped_dir -1 1
23328         test_300_check_default_striped_dir striped_dir 2 -1
23329
23330         #delete default stripe information
23331         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23332                 error "set default stripe on striped dir error"
23333
23334         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23335         for dir in $(find $DIR/$tdir/striped_dir/*); do
23336                 stripe_count=$($LFS getdirstripe -c $dir)
23337                 [ $stripe_count -eq 0 ] ||
23338                         error "expect 1 get $stripe_count for $dir"
23339         done
23340 }
23341 run_test 300h "check default striped directory for striped directory"
23342
23343 test_300i() {
23344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23345         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23346         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23347                 skip "Need MDS version at least 2.7.55"
23348
23349         local stripe_count
23350         local file
23351
23352         mkdir $DIR/$tdir
23353
23354         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23355                 error "set striped dir error"
23356
23357         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23358                 error "create files under striped dir failed"
23359
23360         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23361                 error "set striped hashdir error"
23362
23363         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23364                 error "create dir0 under hash dir failed"
23365         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23366                 error "create dir1 under hash dir failed"
23367         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23368                 error "create dir2 under hash dir failed"
23369
23370         # unfortunately, we need to umount to clear dir layout cache for now
23371         # once we fully implement dir layout, we can drop this
23372         umount_client $MOUNT || error "umount failed"
23373         mount_client $MOUNT || error "mount failed"
23374
23375         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23376         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23377         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23378
23379         #set the stripe to be unknown hash type
23380         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23381         $LCTL set_param fail_loc=0x1901
23382         for ((i = 0; i < 10; i++)); do
23383                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23384                         error "stat f-$i failed"
23385                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23386         done
23387
23388         touch $DIR/$tdir/striped_dir/f0 &&
23389                 error "create under striped dir with unknown hash should fail"
23390
23391         $LCTL set_param fail_loc=0
23392
23393         umount_client $MOUNT || error "umount failed"
23394         mount_client $MOUNT || error "mount failed"
23395
23396         return 0
23397 }
23398 run_test 300i "client handle unknown hash type striped directory"
23399
23400 test_300j() {
23401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23403         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23404                 skip "Need MDS version at least 2.7.55"
23405
23406         local stripe_count
23407         local file
23408
23409         mkdir $DIR/$tdir
23410
23411         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23412         $LCTL set_param fail_loc=0x1702
23413         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23414                 error "set striped dir error"
23415
23416         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23417                 error "create files under striped dir failed"
23418
23419         $LCTL set_param fail_loc=0
23420
23421         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23422
23423         return 0
23424 }
23425 run_test 300j "test large update record"
23426
23427 test_300k() {
23428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23430         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23431                 skip "Need MDS version at least 2.7.55"
23432
23433         # this test needs a huge transaction
23434         local kb
23435         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23436              osd*.$FSNAME-MDT0000.kbytestotal")
23437         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23438
23439         local stripe_count
23440         local file
23441
23442         mkdir $DIR/$tdir
23443
23444         #define OBD_FAIL_LARGE_STRIPE   0x1703
23445         $LCTL set_param fail_loc=0x1703
23446         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23447                 error "set striped dir error"
23448         $LCTL set_param fail_loc=0
23449
23450         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23451                 error "getstripeddir fails"
23452         rm -rf $DIR/$tdir/striped_dir ||
23453                 error "unlink striped dir fails"
23454
23455         return 0
23456 }
23457 run_test 300k "test large striped directory"
23458
23459 test_300l() {
23460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23462         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23463                 skip "Need MDS version at least 2.7.55"
23464
23465         local stripe_index
23466
23467         test_mkdir -p $DIR/$tdir/striped_dir
23468         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23469                         error "chown $RUNAS_ID failed"
23470         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23471                 error "set default striped dir failed"
23472
23473         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23474         $LCTL set_param fail_loc=0x80000158
23475         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23476
23477         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23478         [ $stripe_index -eq 1 ] ||
23479                 error "expect 1 get $stripe_index for $dir"
23480 }
23481 run_test 300l "non-root user to create dir under striped dir with stale layout"
23482
23483 test_300m() {
23484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23485         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23486         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23487                 skip "Need MDS version at least 2.7.55"
23488
23489         mkdir -p $DIR/$tdir/striped_dir
23490         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23491                 error "set default stripes dir error"
23492
23493         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23494
23495         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23496         [ $stripe_count -eq 0 ] ||
23497                         error "expect 0 get $stripe_count for a"
23498
23499         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23500                 error "set default stripes dir error"
23501
23502         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23503
23504         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23505         [ $stripe_count -eq 0 ] ||
23506                         error "expect 0 get $stripe_count for b"
23507
23508         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23509                 error "set default stripes dir error"
23510
23511         mkdir $DIR/$tdir/striped_dir/c &&
23512                 error "default stripe_index is invalid, mkdir c should fails"
23513
23514         rm -rf $DIR/$tdir || error "rmdir fails"
23515 }
23516 run_test 300m "setstriped directory on single MDT FS"
23517
23518 cleanup_300n() {
23519         local list=$(comma_list $(mdts_nodes))
23520
23521         trap 0
23522         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23523 }
23524
23525 test_300n() {
23526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23527         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23528         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23529                 skip "Need MDS version at least 2.7.55"
23530         remote_mds_nodsh && skip "remote MDS with nodsh"
23531
23532         local stripe_index
23533         local list=$(comma_list $(mdts_nodes))
23534
23535         trap cleanup_300n RETURN EXIT
23536         mkdir -p $DIR/$tdir
23537         chmod 777 $DIR/$tdir
23538         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23539                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23540                 error "create striped dir succeeds with gid=0"
23541
23542         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23543         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23544                 error "create striped dir fails with gid=-1"
23545
23546         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23547         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23548                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23549                 error "set default striped dir succeeds with gid=0"
23550
23551
23552         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23553         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23554                 error "set default striped dir fails with gid=-1"
23555
23556
23557         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23558         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23559                                         error "create test_dir fails"
23560         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23561                                         error "create test_dir1 fails"
23562         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23563                                         error "create test_dir2 fails"
23564         cleanup_300n
23565 }
23566 run_test 300n "non-root user to create dir under striped dir with default EA"
23567
23568 test_300o() {
23569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23570         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23571         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23572                 skip "Need MDS version at least 2.7.55"
23573
23574         local numfree1
23575         local numfree2
23576
23577         mkdir -p $DIR/$tdir
23578
23579         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23580         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23581         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23582                 skip "not enough free inodes $numfree1 $numfree2"
23583         fi
23584
23585         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23586         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23587         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23588                 skip "not enough free space $numfree1 $numfree2"
23589         fi
23590
23591         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23592                 error "setdirstripe fails"
23593
23594         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23595                 error "create dirs fails"
23596
23597         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23598         ls $DIR/$tdir/striped_dir > /dev/null ||
23599                 error "ls striped dir fails"
23600         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23601                 error "unlink big striped dir fails"
23602 }
23603 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23604
23605 test_300p() {
23606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23607         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23608         remote_mds_nodsh && skip "remote MDS with nodsh"
23609
23610         mkdir_on_mdt0 $DIR/$tdir
23611
23612         #define OBD_FAIL_OUT_ENOSPC     0x1704
23613         do_facet mds2 lctl set_param fail_loc=0x80001704
23614         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23615                  && error "create striped directory should fail"
23616
23617         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23618
23619         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23620         true
23621 }
23622 run_test 300p "create striped directory without space"
23623
23624 test_300q() {
23625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23626         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23627
23628         local fd=$(free_fd)
23629         local cmd="exec $fd<$tdir"
23630         cd $DIR
23631         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23632         eval $cmd
23633         cmd="exec $fd<&-"
23634         trap "eval $cmd" EXIT
23635         cd $tdir || error "cd $tdir fails"
23636         rmdir  ../$tdir || error "rmdir $tdir fails"
23637         mkdir local_dir && error "create dir succeeds"
23638         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23639         eval $cmd
23640         return 0
23641 }
23642 run_test 300q "create remote directory under orphan directory"
23643
23644 test_300r() {
23645         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23646                 skip "Need MDS version at least 2.7.55" && return
23647         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23648
23649         mkdir $DIR/$tdir
23650
23651         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23652                 error "set striped dir error"
23653
23654         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23655                 error "getstripeddir fails"
23656
23657         local stripe_count
23658         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23659                       awk '/lmv_stripe_count:/ { print $2 }')
23660
23661         [ $MDSCOUNT -ne $stripe_count ] &&
23662                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23663
23664         rm -rf $DIR/$tdir/striped_dir ||
23665                 error "unlink striped dir fails"
23666 }
23667 run_test 300r "test -1 striped directory"
23668
23669 test_300s_helper() {
23670         local count=$1
23671
23672         local stripe_dir=$DIR/$tdir/striped_dir.$count
23673
23674         $LFS mkdir -c $count $stripe_dir ||
23675                 error "lfs mkdir -c error"
23676
23677         $LFS getdirstripe $stripe_dir ||
23678                 error "lfs getdirstripe fails"
23679
23680         local stripe_count
23681         stripe_count=$($LFS getdirstripe $stripe_dir |
23682                       awk '/lmv_stripe_count:/ { print $2 }')
23683
23684         [ $count -ne $stripe_count ] &&
23685                 error_noexit "bad stripe count $stripe_count expected $count"
23686
23687         local dupe_stripes
23688         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23689                 awk '/0x/ {count[$1] += 1}; END {
23690                         for (idx in count) {
23691                                 if (count[idx]>1) {
23692                                         print "index " idx " count " count[idx]
23693                                 }
23694                         }
23695                 }')
23696
23697         if [[ -n "$dupe_stripes" ]] ; then
23698                 lfs getdirstripe $stripe_dir
23699                 error_noexit "Dupe MDT above: $dupe_stripes "
23700         fi
23701
23702         rm -rf $stripe_dir ||
23703                 error_noexit "unlink $stripe_dir fails"
23704 }
23705
23706 test_300s() {
23707         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23708                 skip "Need MDS version at least 2.7.55" && return
23709         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23710
23711         mkdir $DIR/$tdir
23712         for count in $(seq 2 $MDSCOUNT); do
23713                 test_300s_helper $count
23714         done
23715 }
23716 run_test 300s "test lfs mkdir -c without -i"
23717
23718 prepare_remote_file() {
23719         mkdir $DIR/$tdir/src_dir ||
23720                 error "create remote source failed"
23721
23722         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23723                  error "cp to remote source failed"
23724         touch $DIR/$tdir/src_dir/a
23725
23726         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23727                 error "create remote target dir failed"
23728
23729         touch $DIR/$tdir/tgt_dir/b
23730
23731         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23732                 error "rename dir cross MDT failed!"
23733
23734         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23735                 error "src_child still exists after rename"
23736
23737         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23738                 error "missing file(a) after rename"
23739
23740         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23741                 error "diff after rename"
23742 }
23743
23744 test_310a() {
23745         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23747
23748         local remote_file=$DIR/$tdir/tgt_dir/b
23749
23750         mkdir -p $DIR/$tdir
23751
23752         prepare_remote_file || error "prepare remote file failed"
23753
23754         #open-unlink file
23755         $OPENUNLINK $remote_file $remote_file ||
23756                 error "openunlink $remote_file failed"
23757         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23758 }
23759 run_test 310a "open unlink remote file"
23760
23761 test_310b() {
23762         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23764
23765         local remote_file=$DIR/$tdir/tgt_dir/b
23766
23767         mkdir -p $DIR/$tdir
23768
23769         prepare_remote_file || error "prepare remote file failed"
23770
23771         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23772         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23773         $CHECKSTAT -t file $remote_file || error "check file failed"
23774 }
23775 run_test 310b "unlink remote file with multiple links while open"
23776
23777 test_310c() {
23778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23779         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23780
23781         local remote_file=$DIR/$tdir/tgt_dir/b
23782
23783         mkdir -p $DIR/$tdir
23784
23785         prepare_remote_file || error "prepare remote file failed"
23786
23787         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23788         multiop_bg_pause $remote_file O_uc ||
23789                         error "mulitop failed for remote file"
23790         MULTIPID=$!
23791         $MULTIOP $DIR/$tfile Ouc
23792         kill -USR1 $MULTIPID
23793         wait $MULTIPID
23794 }
23795 run_test 310c "open-unlink remote file with multiple links"
23796
23797 #LU-4825
23798 test_311() {
23799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23800         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23801         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23802                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23803         remote_mds_nodsh && skip "remote MDS with nodsh"
23804
23805         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23806         local mdts=$(comma_list $(mdts_nodes))
23807
23808         mkdir -p $DIR/$tdir
23809         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23810         createmany -o $DIR/$tdir/$tfile. 1000
23811
23812         # statfs data is not real time, let's just calculate it
23813         old_iused=$((old_iused + 1000))
23814
23815         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23816                         osp.*OST0000*MDT0000.create_count")
23817         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23818                                 osp.*OST0000*MDT0000.max_create_count")
23819         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23820
23821         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23822         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23823         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23824
23825         unlinkmany $DIR/$tdir/$tfile. 1000
23826
23827         do_nodes $mdts "$LCTL set_param -n \
23828                         osp.*OST0000*.max_create_count=$max_count"
23829         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23830                 do_nodes $mdts "$LCTL set_param -n \
23831                                 osp.*OST0000*.create_count=$count"
23832         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23833                         grep "=0" && error "create_count is zero"
23834
23835         local new_iused
23836         for i in $(seq 120); do
23837                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23838                 # system may be too busy to destroy all objs in time, use
23839                 # a somewhat small value to not fail autotest
23840                 [ $((old_iused - new_iused)) -gt 400 ] && break
23841                 sleep 1
23842         done
23843
23844         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23845         [ $((old_iused - new_iused)) -gt 400 ] ||
23846                 error "objs not destroyed after unlink"
23847 }
23848 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23849
23850 zfs_oid_to_objid()
23851 {
23852         local ost=$1
23853         local objid=$2
23854
23855         local vdevdir=$(dirname $(facet_vdevice $ost))
23856         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23857         local zfs_zapid=$(do_facet $ost $cmd |
23858                           grep -w "/O/0/d$((objid%32))" -C 5 |
23859                           awk '/Object/{getline; print $1}')
23860         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23861                           awk "/$objid = /"'{printf $3}')
23862
23863         echo $zfs_objid
23864 }
23865
23866 zfs_object_blksz() {
23867         local ost=$1
23868         local objid=$2
23869
23870         local vdevdir=$(dirname $(facet_vdevice $ost))
23871         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23872         local blksz=$(do_facet $ost $cmd $objid |
23873                       awk '/dblk/{getline; printf $4}')
23874
23875         case "${blksz: -1}" in
23876                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23877                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23878                 *) ;;
23879         esac
23880
23881         echo $blksz
23882 }
23883
23884 test_312() { # LU-4856
23885         remote_ost_nodsh && skip "remote OST with nodsh"
23886         [ "$ost1_FSTYPE" = "zfs" ] ||
23887                 skip_env "the test only applies to zfs"
23888
23889         local max_blksz=$(do_facet ost1 \
23890                           $ZFS get -p recordsize $(facet_device ost1) |
23891                           awk '!/VALUE/{print $3}')
23892
23893         # to make life a little bit easier
23894         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23895         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23896
23897         local tf=$DIR/$tdir/$tfile
23898         touch $tf
23899         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23900
23901         # Get ZFS object id
23902         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23903         # block size change by sequential overwrite
23904         local bs
23905
23906         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23907                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23908
23909                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23910                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23911         done
23912         rm -f $tf
23913
23914         # block size change by sequential append write
23915         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23916         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23917         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23918         local count
23919
23920         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23921                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23922                         oflag=sync conv=notrunc
23923
23924                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23925                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23926                         error "blksz error, actual $blksz, " \
23927                                 "expected: 2 * $count * $PAGE_SIZE"
23928         done
23929         rm -f $tf
23930
23931         # random write
23932         touch $tf
23933         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23934         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23935
23936         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23937         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23938         [ $blksz -eq $PAGE_SIZE ] ||
23939                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23940
23941         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23942         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23943         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23944
23945         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23946         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23947         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23948 }
23949 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23950
23951 test_313() {
23952         remote_ost_nodsh && skip "remote OST with nodsh"
23953
23954         local file=$DIR/$tfile
23955
23956         rm -f $file
23957         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23958
23959         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23960         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23961         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23962                 error "write should failed"
23963         do_facet ost1 "$LCTL set_param fail_loc=0"
23964         rm -f $file
23965 }
23966 run_test 313 "io should fail after last_rcvd update fail"
23967
23968 test_314() {
23969         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23970
23971         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23972         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23973         rm -f $DIR/$tfile
23974         wait_delete_completed
23975         do_facet ost1 "$LCTL set_param fail_loc=0"
23976 }
23977 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23978
23979 test_315() { # LU-618
23980         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23981
23982         local file=$DIR/$tfile
23983         rm -f $file
23984
23985         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23986                 error "multiop file write failed"
23987         $MULTIOP $file oO_RDONLY:r4063232_c &
23988         PID=$!
23989
23990         sleep 2
23991
23992         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23993         kill -USR1 $PID
23994
23995         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23996         rm -f $file
23997 }
23998 run_test 315 "read should be accounted"
23999
24000 test_316() {
24001         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24002         large_xattr_enabled || skip_env "ea_inode feature disabled"
24003
24004         rm -rf $DIR/$tdir/d
24005         mkdir -p $DIR/$tdir/d
24006         chown nobody $DIR/$tdir/d
24007         touch $DIR/$tdir/d/file
24008
24009         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24010 }
24011 run_test 316 "lfs mv"
24012
24013 test_317() {
24014         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24015                 skip "Need MDS version at least 2.11.53"
24016         if [ "$ost1_FSTYPE" == "zfs" ]; then
24017                 skip "LU-10370: no implementation for ZFS"
24018         fi
24019
24020         local trunc_sz
24021         local grant_blk_size
24022
24023         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24024                         awk '/grant_block_size:/ { print $2; exit; }')
24025         #
24026         # Create File of size 5M. Truncate it to below size's and verify
24027         # blocks count.
24028         #
24029         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24030                 error "Create file $DIR/$tfile failed"
24031         stack_trap "rm -f $DIR/$tfile" EXIT
24032
24033         for trunc_sz in 2097152 4097 4000 509 0; do
24034                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24035                         error "truncate $tfile to $trunc_sz failed"
24036                 local sz=$(stat --format=%s $DIR/$tfile)
24037                 local blk=$(stat --format=%b $DIR/$tfile)
24038                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24039                                      grant_blk_size) * 8))
24040
24041                 if [[ $blk -ne $trunc_blk ]]; then
24042                         $(which stat) $DIR/$tfile
24043                         error "Expected Block $trunc_blk got $blk for $tfile"
24044                 fi
24045
24046                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24047                         error "Expected Size $trunc_sz got $sz for $tfile"
24048         done
24049
24050         #
24051         # sparse file test
24052         # Create file with a hole and write actual 65536 bytes which aligned
24053         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24054         #
24055         local bs=65536
24056         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24057                 error "Create file : $DIR/$tfile"
24058
24059         #
24060         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24061         # blocks. The block count must drop to 8.
24062         #
24063         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24064                 ((bs - grant_blk_size) + 1)))
24065         $TRUNCATE $DIR/$tfile $trunc_sz ||
24066                 error "truncate $tfile to $trunc_sz failed"
24067
24068         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24069         sz=$(stat --format=%s $DIR/$tfile)
24070         blk=$(stat --format=%b $DIR/$tfile)
24071
24072         if [[ $blk -ne $trunc_bsz ]]; then
24073                 $(which stat) $DIR/$tfile
24074                 error "Expected Block $trunc_bsz got $blk for $tfile"
24075         fi
24076
24077         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24078                 error "Expected Size $trunc_sz got $sz for $tfile"
24079 }
24080 run_test 317 "Verify blocks get correctly update after truncate"
24081
24082 test_318() {
24083         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24084         local old_max_active=$($LCTL get_param -n \
24085                             ${llite_name}.max_read_ahead_async_active \
24086                             2>/dev/null)
24087
24088         $LCTL set_param llite.*.max_read_ahead_async_active=256
24089         local max_active=$($LCTL get_param -n \
24090                            ${llite_name}.max_read_ahead_async_active \
24091                            2>/dev/null)
24092         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24093
24094         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24095                 error "set max_read_ahead_async_active should succeed"
24096
24097         $LCTL set_param llite.*.max_read_ahead_async_active=512
24098         max_active=$($LCTL get_param -n \
24099                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24100         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24101
24102         # restore @max_active
24103         [ $old_max_active -ne 0 ] && $LCTL set_param \
24104                 llite.*.max_read_ahead_async_active=$old_max_active
24105
24106         local old_threshold=$($LCTL get_param -n \
24107                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24108         local max_per_file_mb=$($LCTL get_param -n \
24109                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24110
24111         local invalid=$(($max_per_file_mb + 1))
24112         $LCTL set_param \
24113                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24114                         && error "set $invalid should fail"
24115
24116         local valid=$(($invalid - 1))
24117         $LCTL set_param \
24118                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24119                         error "set $valid should succeed"
24120         local threshold=$($LCTL get_param -n \
24121                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24122         [ $threshold -eq $valid ] || error \
24123                 "expect threshold $valid got $threshold"
24124         $LCTL set_param \
24125                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24126 }
24127 run_test 318 "Verify async readahead tunables"
24128
24129 test_319() {
24130         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24131
24132         local before=$(date +%s)
24133         local evict
24134         local mdir=$DIR/$tdir
24135         local file=$mdir/xxx
24136
24137         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24138         touch $file
24139
24140 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24141         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24142         $LFS mv -m1 $file &
24143
24144         sleep 1
24145         dd if=$file of=/dev/null
24146         wait
24147         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24148           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24149
24150         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24151 }
24152 run_test 319 "lost lease lock on migrate error"
24153
24154 test_398a() { # LU-4198
24155         local ost1_imp=$(get_osc_import_name client ost1)
24156         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24157                          cut -d'.' -f2)
24158
24159         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24160         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24161
24162         # request a new lock on client
24163         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24164
24165         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24166         local lock_count=$($LCTL get_param -n \
24167                            ldlm.namespaces.$imp_name.lru_size)
24168         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24169
24170         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24171
24172         # no lock cached, should use lockless IO and not enqueue new lock
24173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24174         lock_count=$($LCTL get_param -n \
24175                      ldlm.namespaces.$imp_name.lru_size)
24176         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24177 }
24178 run_test 398a "direct IO should cancel lock otherwise lockless"
24179
24180 test_398b() { # LU-4198
24181         which fio || skip_env "no fio installed"
24182         $LFS setstripe -c -1 $DIR/$tfile
24183
24184         local size=12
24185         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24186
24187         local njobs=4
24188         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24189         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24190                 --numjobs=$njobs --fallocate=none \
24191                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24192                 --filename=$DIR/$tfile &
24193         bg_pid=$!
24194
24195         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24196         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24197                 --numjobs=$njobs --fallocate=none \
24198                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24199                 --filename=$DIR/$tfile || true
24200         wait $bg_pid
24201
24202         rm -f $DIR/$tfile
24203 }
24204 run_test 398b "DIO and buffer IO race"
24205
24206 test_398c() { # LU-4198
24207         local ost1_imp=$(get_osc_import_name client ost1)
24208         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24209                          cut -d'.' -f2)
24210
24211         which fio || skip_env "no fio installed"
24212
24213         saved_debug=$($LCTL get_param -n debug)
24214         $LCTL set_param debug=0
24215
24216         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24217         ((size /= 1024)) # by megabytes
24218         ((size /= 2)) # write half of the OST at most
24219         [ $size -gt 40 ] && size=40 #reduce test time anyway
24220
24221         $LFS setstripe -c 1 $DIR/$tfile
24222
24223         # it seems like ldiskfs reserves more space than necessary if the
24224         # writing blocks are not mapped, so it extends the file firstly
24225         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24226         cancel_lru_locks osc
24227
24228         # clear and verify rpc_stats later
24229         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24230
24231         local njobs=4
24232         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24233         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24234                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24235                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24236                 --filename=$DIR/$tfile
24237         [ $? -eq 0 ] || error "fio write error"
24238
24239         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24240                 error "Locks were requested while doing AIO"
24241
24242         # get the percentage of 1-page I/O
24243         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24244                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24245                 awk '{print $7}')
24246         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24247
24248         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24249         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24250                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24251                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24252                 --filename=$DIR/$tfile
24253         [ $? -eq 0 ] || error "fio mixed read write error"
24254
24255         echo "AIO with large block size ${size}M"
24256         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24257                 --numjobs=1 --fallocate=none --ioengine=libaio \
24258                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24259                 --filename=$DIR/$tfile
24260         [ $? -eq 0 ] || error "fio large block size failed"
24261
24262         rm -f $DIR/$tfile
24263         $LCTL set_param debug="$saved_debug"
24264 }
24265 run_test 398c "run fio to test AIO"
24266
24267 test_398d() { #  LU-13846
24268         which aiocp || skip_env "no aiocp installed"
24269         local aio_file=$DIR/$tfile.aio
24270
24271         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24272
24273         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24274         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24275         stack_trap "rm -f $DIR/$tfile $aio_file"
24276
24277         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24278
24279         # make sure we don't crash and fail properly
24280         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24281                 error "aio not aligned with PAGE SIZE should fail"
24282
24283         rm -f $DIR/$tfile $aio_file
24284 }
24285 run_test 398d "run aiocp to verify block size > stripe size"
24286
24287 test_398e() {
24288         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24289         touch $DIR/$tfile.new
24290         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24291 }
24292 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24293
24294 test_398f() { #  LU-14687
24295         which aiocp || skip_env "no aiocp installed"
24296         local aio_file=$DIR/$tfile.aio
24297
24298         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24299
24300         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24301         stack_trap "rm -f $DIR/$tfile $aio_file"
24302
24303         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24304         $LCTL set_param fail_loc=0x1418
24305         # make sure we don't crash and fail properly
24306         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24307                 error "aio with page allocation failure succeeded"
24308         $LCTL set_param fail_loc=0
24309         diff $DIR/$tfile $aio_file
24310         [[ $? != 0 ]] || error "no diff after failed aiocp"
24311 }
24312 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24313
24314 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24315 # stripe and i/o size must be > stripe size
24316 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24317 # single RPC in flight.  This test shows async DIO submission is working by
24318 # showing multiple RPCs in flight.
24319 test_398g() { #  LU-13798
24320         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24321
24322         # We need to do some i/o first to acquire enough grant to put our RPCs
24323         # in flight; otherwise a new connection may not have enough grant
24324         # available
24325         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24326                 error "parallel dio failed"
24327         stack_trap "rm -f $DIR/$tfile"
24328
24329         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24330         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24331         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24332         stack_trap "$LCTL set_param -n $pages_per_rpc"
24333
24334         # Recreate file so it's empty
24335         rm -f $DIR/$tfile
24336         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24337         #Pause rpc completion to guarantee we see multiple rpcs in flight
24338         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24339         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24340         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24341
24342         # Clear rpc stats
24343         $LCTL set_param osc.*.rpc_stats=c
24344
24345         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24346                 error "parallel dio failed"
24347         stack_trap "rm -f $DIR/$tfile"
24348
24349         $LCTL get_param osc.*-OST0000-*.rpc_stats
24350         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24351                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24352                 grep "8:" | awk '{print $8}')
24353         # We look at the "8 rpcs in flight" field, and verify A) it is present
24354         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24355         # as expected for an 8M DIO to a file with 1M stripes.
24356         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24357
24358         # Verify turning off parallel dio works as expected
24359         # Clear rpc stats
24360         $LCTL set_param osc.*.rpc_stats=c
24361         $LCTL set_param llite.*.parallel_dio=0
24362         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24363
24364         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24365                 error "dio with parallel dio disabled failed"
24366
24367         # Ideally, we would see only one RPC in flight here, but there is an
24368         # unavoidable race between i/o completion and RPC in flight counting,
24369         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24370         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24371         # So instead we just verify it's always < 8.
24372         $LCTL get_param osc.*-OST0000-*.rpc_stats
24373         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24374                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24375                 grep '^$' -B1 | grep . | awk '{print $1}')
24376         [ $ret != "8:" ] ||
24377                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24378 }
24379 run_test 398g "verify parallel dio async RPC submission"
24380
24381 test_398h() { #  LU-13798
24382         local dio_file=$DIR/$tfile.dio
24383
24384         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24385
24386         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24387         stack_trap "rm -f $DIR/$tfile $dio_file"
24388
24389         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24390                 error "parallel dio failed"
24391         diff $DIR/$tfile $dio_file
24392         [[ $? == 0 ]] || error "file diff after aiocp"
24393 }
24394 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24395
24396 test_398i() { #  LU-13798
24397         local dio_file=$DIR/$tfile.dio
24398
24399         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24400
24401         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24402         stack_trap "rm -f $DIR/$tfile $dio_file"
24403
24404         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24405         $LCTL set_param fail_loc=0x1418
24406         # make sure we don't crash and fail properly
24407         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24408                 error "parallel dio page allocation failure succeeded"
24409         diff $DIR/$tfile $dio_file
24410         [[ $? != 0 ]] || error "no diff after failed aiocp"
24411 }
24412 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24413
24414 test_398j() { #  LU-13798
24415         # Stripe size > RPC size but less than i/o size tests split across
24416         # stripes and RPCs for individual i/o op
24417         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24418
24419         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24420         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24421         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24422         stack_trap "$LCTL set_param -n $pages_per_rpc"
24423
24424         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24425                 error "parallel dio write failed"
24426         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24427
24428         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24429                 error "parallel dio read failed"
24430         diff $DIR/$tfile $DIR/$tfile.2
24431         [[ $? == 0 ]] || error "file diff after parallel dio read"
24432 }
24433 run_test 398j "test parallel dio where stripe size > rpc_size"
24434
24435 test_398k() { #  LU-13798
24436         wait_delete_completed
24437         wait_mds_ost_sync
24438
24439         # 4 stripe file; we will cause out of space on OST0
24440         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24441
24442         # Fill OST0 (if it's not too large)
24443         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24444                    head -n1)
24445         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24446                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24447         fi
24448         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24449         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24450                 error "dd should fill OST0"
24451         stack_trap "rm -f $DIR/$tfile.1"
24452
24453         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24454         err=$?
24455
24456         ls -la $DIR/$tfile
24457         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24458                 error "file is not 0 bytes in size"
24459
24460         # dd above should not succeed, but don't error until here so we can
24461         # get debug info above
24462         [[ $err != 0 ]] ||
24463                 error "parallel dio write with enospc succeeded"
24464         stack_trap "rm -f $DIR/$tfile"
24465 }
24466 run_test 398k "test enospc on first stripe"
24467
24468 test_398l() { #  LU-13798
24469         wait_delete_completed
24470         wait_mds_ost_sync
24471
24472         # 4 stripe file; we will cause out of space on OST0
24473         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24474         # happens on the second i/o chunk we issue
24475         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24476
24477         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24478         stack_trap "rm -f $DIR/$tfile"
24479
24480         # Fill OST0 (if it's not too large)
24481         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24482                    head -n1)
24483         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24484                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24485         fi
24486         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24487         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24488                 error "dd should fill OST0"
24489         stack_trap "rm -f $DIR/$tfile.1"
24490
24491         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24492         err=$?
24493         stack_trap "rm -f $DIR/$tfile.2"
24494
24495         # Check that short write completed as expected
24496         ls -la $DIR/$tfile.2
24497         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24498                 error "file is not 1M in size"
24499
24500         # dd above should not succeed, but don't error until here so we can
24501         # get debug info above
24502         [[ $err != 0 ]] ||
24503                 error "parallel dio write with enospc succeeded"
24504
24505         # Truncate source file to same length as output file and diff them
24506         $TRUNCATE $DIR/$tfile 1048576
24507         diff $DIR/$tfile $DIR/$tfile.2
24508         [[ $? == 0 ]] || error "data incorrect after short write"
24509 }
24510 run_test 398l "test enospc on intermediate stripe/RPC"
24511
24512 test_398m() { #  LU-13798
24513         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24514
24515         # Set up failure on OST0, the first stripe:
24516         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24517         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24518         # So this fail_val specifies OST0
24519         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24520         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24521
24522         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24523                 error "parallel dio write with failure on first stripe succeeded"
24524         stack_trap "rm -f $DIR/$tfile"
24525         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24526
24527         # Place data in file for read
24528         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24529                 error "parallel dio write failed"
24530
24531         # Fail read on OST0, first stripe
24532         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24533         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24534         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24535                 error "parallel dio read with error on first stripe succeeded"
24536         rm -f $DIR/$tfile.2
24537         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24538
24539         # Switch to testing on OST1, second stripe
24540         # Clear file contents, maintain striping
24541         echo > $DIR/$tfile
24542         # Set up failure on OST1, second stripe:
24543         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24544         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24545
24546         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24547                 error "parallel dio write with failure on first stripe succeeded"
24548         stack_trap "rm -f $DIR/$tfile"
24549         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24550
24551         # Place data in file for read
24552         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24553                 error "parallel dio write failed"
24554
24555         # Fail read on OST1, second stripe
24556         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24557         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24558         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24559                 error "parallel dio read with error on first stripe succeeded"
24560         rm -f $DIR/$tfile.2
24561         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24562 }
24563 run_test 398m "test RPC failures with parallel dio"
24564
24565 # Parallel submission of DIO should not cause problems for append, but it's
24566 # important to verify.
24567 test_398n() { #  LU-13798
24568         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24569
24570         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24571                 error "dd to create source file failed"
24572         stack_trap "rm -f $DIR/$tfile"
24573
24574         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24575                 error "parallel dio write with failure on second stripe succeeded"
24576         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24577         diff $DIR/$tfile $DIR/$tfile.1
24578         [[ $? == 0 ]] || error "data incorrect after append"
24579
24580 }
24581 run_test 398n "test append with parallel DIO"
24582
24583 test_fake_rw() {
24584         local read_write=$1
24585         if [ "$read_write" = "write" ]; then
24586                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24587         elif [ "$read_write" = "read" ]; then
24588                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24589         else
24590                 error "argument error"
24591         fi
24592
24593         # turn off debug for performance testing
24594         local saved_debug=$($LCTL get_param -n debug)
24595         $LCTL set_param debug=0
24596
24597         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24598
24599         # get ost1 size - $FSNAME-OST0000
24600         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24601         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24602         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24603
24604         if [ "$read_write" = "read" ]; then
24605                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24606         fi
24607
24608         local start_time=$(date +%s.%N)
24609         $dd_cmd bs=1M count=$blocks oflag=sync ||
24610                 error "real dd $read_write error"
24611         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24612
24613         if [ "$read_write" = "write" ]; then
24614                 rm -f $DIR/$tfile
24615         fi
24616
24617         # define OBD_FAIL_OST_FAKE_RW           0x238
24618         do_facet ost1 $LCTL set_param fail_loc=0x238
24619
24620         local start_time=$(date +%s.%N)
24621         $dd_cmd bs=1M count=$blocks oflag=sync ||
24622                 error "fake dd $read_write error"
24623         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24624
24625         if [ "$read_write" = "write" ]; then
24626                 # verify file size
24627                 cancel_lru_locks osc
24628                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24629                         error "$tfile size not $blocks MB"
24630         fi
24631         do_facet ost1 $LCTL set_param fail_loc=0
24632
24633         echo "fake $read_write $duration_fake vs. normal $read_write" \
24634                 "$duration in seconds"
24635         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24636                 error_not_in_vm "fake write is slower"
24637
24638         $LCTL set_param -n debug="$saved_debug"
24639         rm -f $DIR/$tfile
24640 }
24641 test_399a() { # LU-7655 for OST fake write
24642         remote_ost_nodsh && skip "remote OST with nodsh"
24643
24644         test_fake_rw write
24645 }
24646 run_test 399a "fake write should not be slower than normal write"
24647
24648 test_399b() { # LU-8726 for OST fake read
24649         remote_ost_nodsh && skip "remote OST with nodsh"
24650         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24651                 skip_env "ldiskfs only test"
24652         fi
24653
24654         test_fake_rw read
24655 }
24656 run_test 399b "fake read should not be slower than normal read"
24657
24658 test_400a() { # LU-1606, was conf-sanity test_74
24659         if ! which $CC > /dev/null 2>&1; then
24660                 skip_env "$CC is not installed"
24661         fi
24662
24663         local extra_flags=''
24664         local out=$TMP/$tfile
24665         local prefix=/usr/include/lustre
24666         local prog
24667
24668         # Oleg removes c files in his test rig so test if any c files exist
24669         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24670                 skip_env "Needed c test files are missing"
24671
24672         if ! [[ -d $prefix ]]; then
24673                 # Assume we're running in tree and fixup the include path.
24674                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24675                 extra_flags+=" -L$LUSTRE/utils/.lib"
24676         fi
24677
24678         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24679                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24680                         error "client api broken"
24681         done
24682         rm -f $out
24683 }
24684 run_test 400a "Lustre client api program can compile and link"
24685
24686 test_400b() { # LU-1606, LU-5011
24687         local header
24688         local out=$TMP/$tfile
24689         local prefix=/usr/include/linux/lustre
24690
24691         # We use a hard coded prefix so that this test will not fail
24692         # when run in tree. There are headers in lustre/include/lustre/
24693         # that are not packaged (like lustre_idl.h) and have more
24694         # complicated include dependencies (like config.h and lnet/types.h).
24695         # Since this test about correct packaging we just skip them when
24696         # they don't exist (see below) rather than try to fixup cppflags.
24697
24698         if ! which $CC > /dev/null 2>&1; then
24699                 skip_env "$CC is not installed"
24700         fi
24701
24702         for header in $prefix/*.h; do
24703                 if ! [[ -f "$header" ]]; then
24704                         continue
24705                 fi
24706
24707                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24708                         continue # lustre_ioctl.h is internal header
24709                 fi
24710
24711                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24712                         error "cannot compile '$header'"
24713         done
24714         rm -f $out
24715 }
24716 run_test 400b "packaged headers can be compiled"
24717
24718 test_401a() { #LU-7437
24719         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24720         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24721
24722         #count the number of parameters by "list_param -R"
24723         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24724         #count the number of parameters by listing proc files
24725         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24726         echo "proc_dirs='$proc_dirs'"
24727         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24728         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24729                       sort -u | wc -l)
24730
24731         [ $params -eq $procs ] ||
24732                 error "found $params parameters vs. $procs proc files"
24733
24734         # test the list_param -D option only returns directories
24735         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24736         #count the number of parameters by listing proc directories
24737         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24738                 sort -u | wc -l)
24739
24740         [ $params -eq $procs ] ||
24741                 error "found $params parameters vs. $procs proc files"
24742 }
24743 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24744
24745 test_401b() {
24746         # jobid_var may not allow arbitrary values, so use jobid_name
24747         # if available
24748         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24749                 local testname=jobid_name tmp='testing%p'
24750         else
24751                 local testname=jobid_var tmp=testing
24752         fi
24753
24754         local save=$($LCTL get_param -n $testname)
24755
24756         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24757                 error "no error returned when setting bad parameters"
24758
24759         local jobid_new=$($LCTL get_param -n foe $testname baz)
24760         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24761
24762         $LCTL set_param -n fog=bam $testname=$save bat=fog
24763         local jobid_old=$($LCTL get_param -n foe $testname bag)
24764         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24765 }
24766 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24767
24768 test_401c() {
24769         # jobid_var may not allow arbitrary values, so use jobid_name
24770         # if available
24771         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24772                 local testname=jobid_name
24773         else
24774                 local testname=jobid_var
24775         fi
24776
24777         local jobid_var_old=$($LCTL get_param -n $testname)
24778         local jobid_var_new
24779
24780         $LCTL set_param $testname= &&
24781                 error "no error returned for 'set_param a='"
24782
24783         jobid_var_new=$($LCTL get_param -n $testname)
24784         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24785                 error "$testname was changed by setting without value"
24786
24787         $LCTL set_param $testname &&
24788                 error "no error returned for 'set_param a'"
24789
24790         jobid_var_new=$($LCTL get_param -n $testname)
24791         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24792                 error "$testname was changed by setting without value"
24793 }
24794 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24795
24796 test_401d() {
24797         # jobid_var may not allow arbitrary values, so use jobid_name
24798         # if available
24799         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24800                 local testname=jobid_name new_value='foo=bar%p'
24801         else
24802                 local testname=jobid_var new_valuie=foo=bar
24803         fi
24804
24805         local jobid_var_old=$($LCTL get_param -n $testname)
24806         local jobid_var_new
24807
24808         $LCTL set_param $testname=$new_value ||
24809                 error "'set_param a=b' did not accept a value containing '='"
24810
24811         jobid_var_new=$($LCTL get_param -n $testname)
24812         [[ "$jobid_var_new" == "$new_value" ]] ||
24813                 error "'set_param a=b' failed on a value containing '='"
24814
24815         # Reset the $testname to test the other format
24816         $LCTL set_param $testname=$jobid_var_old
24817         jobid_var_new=$($LCTL get_param -n $testname)
24818         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24819                 error "failed to reset $testname"
24820
24821         $LCTL set_param $testname $new_value ||
24822                 error "'set_param a b' did not accept a value containing '='"
24823
24824         jobid_var_new=$($LCTL get_param -n $testname)
24825         [[ "$jobid_var_new" == "$new_value" ]] ||
24826                 error "'set_param a b' failed on a value containing '='"
24827
24828         $LCTL set_param $testname $jobid_var_old
24829         jobid_var_new=$($LCTL get_param -n $testname)
24830         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24831                 error "failed to reset $testname"
24832 }
24833 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24834
24835 test_401e() { # LU-14779
24836         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24837                 error "lctl list_param MGC* failed"
24838         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24839         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24840                 error "lctl get_param lru_size failed"
24841 }
24842 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24843
24844 test_402() {
24845         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24846         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24847                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24848         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24849                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24850                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24851         remote_mds_nodsh && skip "remote MDS with nodsh"
24852
24853         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24854 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24855         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24856         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24857                 echo "Touch failed - OK"
24858 }
24859 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24860
24861 test_403() {
24862         local file1=$DIR/$tfile.1
24863         local file2=$DIR/$tfile.2
24864         local tfile=$TMP/$tfile
24865
24866         rm -f $file1 $file2 $tfile
24867
24868         touch $file1
24869         ln $file1 $file2
24870
24871         # 30 sec OBD_TIMEOUT in ll_getattr()
24872         # right before populating st_nlink
24873         $LCTL set_param fail_loc=0x80001409
24874         stat -c %h $file1 > $tfile &
24875
24876         # create an alias, drop all locks and reclaim the dentry
24877         < $file2
24878         cancel_lru_locks mdc
24879         cancel_lru_locks osc
24880         sysctl -w vm.drop_caches=2
24881
24882         wait
24883
24884         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24885
24886         rm -f $tfile $file1 $file2
24887 }
24888 run_test 403 "i_nlink should not drop to zero due to aliasing"
24889
24890 test_404() { # LU-6601
24891         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24892                 skip "Need server version newer than 2.8.52"
24893         remote_mds_nodsh && skip "remote MDS with nodsh"
24894
24895         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24896                 awk '/osp .*-osc-MDT/ { print $4}')
24897
24898         local osp
24899         for osp in $mosps; do
24900                 echo "Deactivate: " $osp
24901                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24902                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24903                         awk -vp=$osp '$4 == p { print $2 }')
24904                 [ $stat = IN ] || {
24905                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24906                         error "deactivate error"
24907                 }
24908                 echo "Activate: " $osp
24909                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24910                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24911                         awk -vp=$osp '$4 == p { print $2 }')
24912                 [ $stat = UP ] || {
24913                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24914                         error "activate error"
24915                 }
24916         done
24917 }
24918 run_test 404 "validate manual {de}activated works properly for OSPs"
24919
24920 test_405() {
24921         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24922         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24923                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24924                         skip "Layout swap lock is not supported"
24925
24926         check_swap_layouts_support
24927         check_swap_layout_no_dom $DIR
24928
24929         test_mkdir $DIR/$tdir
24930         swap_lock_test -d $DIR/$tdir ||
24931                 error "One layout swap locked test failed"
24932 }
24933 run_test 405 "Various layout swap lock tests"
24934
24935 test_406() {
24936         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24937         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24938         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24940         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24941                 skip "Need MDS version at least 2.8.50"
24942
24943         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24944         local test_pool=$TESTNAME
24945
24946         pool_add $test_pool || error "pool_add failed"
24947         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24948                 error "pool_add_targets failed"
24949
24950         save_layout_restore_at_exit $MOUNT
24951
24952         # parent set default stripe count only, child will stripe from both
24953         # parent and fs default
24954         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24955                 error "setstripe $MOUNT failed"
24956         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24957         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24958         for i in $(seq 10); do
24959                 local f=$DIR/$tdir/$tfile.$i
24960                 touch $f || error "touch failed"
24961                 local count=$($LFS getstripe -c $f)
24962                 [ $count -eq $OSTCOUNT ] ||
24963                         error "$f stripe count $count != $OSTCOUNT"
24964                 local offset=$($LFS getstripe -i $f)
24965                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24966                 local size=$($LFS getstripe -S $f)
24967                 [ $size -eq $((def_stripe_size * 2)) ] ||
24968                         error "$f stripe size $size != $((def_stripe_size * 2))"
24969                 local pool=$($LFS getstripe -p $f)
24970                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24971         done
24972
24973         # change fs default striping, delete parent default striping, now child
24974         # will stripe from new fs default striping only
24975         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24976                 error "change $MOUNT default stripe failed"
24977         $LFS setstripe -c 0 $DIR/$tdir ||
24978                 error "delete $tdir default stripe failed"
24979         for i in $(seq 11 20); do
24980                 local f=$DIR/$tdir/$tfile.$i
24981                 touch $f || error "touch $f failed"
24982                 local count=$($LFS getstripe -c $f)
24983                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24984                 local offset=$($LFS getstripe -i $f)
24985                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24986                 local size=$($LFS getstripe -S $f)
24987                 [ $size -eq $def_stripe_size ] ||
24988                         error "$f stripe size $size != $def_stripe_size"
24989                 local pool=$($LFS getstripe -p $f)
24990                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24991         done
24992
24993         unlinkmany $DIR/$tdir/$tfile. 1 20
24994
24995         local f=$DIR/$tdir/$tfile
24996         pool_remove_all_targets $test_pool $f
24997         pool_remove $test_pool $f
24998 }
24999 run_test 406 "DNE support fs default striping"
25000
25001 test_407() {
25002         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25003         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25004                 skip "Need MDS version at least 2.8.55"
25005         remote_mds_nodsh && skip "remote MDS with nodsh"
25006
25007         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25008                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25009         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25010                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25011         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25012
25013         #define OBD_FAIL_DT_TXN_STOP    0x2019
25014         for idx in $(seq $MDSCOUNT); do
25015                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25016         done
25017         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25018         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25019                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25020         true
25021 }
25022 run_test 407 "transaction fail should cause operation fail"
25023
25024 test_408() {
25025         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25026
25027         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25028         lctl set_param fail_loc=0x8000040a
25029         # let ll_prepare_partial_page() fail
25030         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25031
25032         rm -f $DIR/$tfile
25033
25034         # create at least 100 unused inodes so that
25035         # shrink_icache_memory(0) should not return 0
25036         touch $DIR/$tfile-{0..100}
25037         rm -f $DIR/$tfile-{0..100}
25038         sync
25039
25040         echo 2 > /proc/sys/vm/drop_caches
25041 }
25042 run_test 408 "drop_caches should not hang due to page leaks"
25043
25044 test_409()
25045 {
25046         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25047
25048         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25049         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25050         touch $DIR/$tdir/guard || error "(2) Fail to create"
25051
25052         local PREFIX=$(str_repeat 'A' 128)
25053         echo "Create 1K hard links start at $(date)"
25054         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25055                 error "(3) Fail to hard link"
25056
25057         echo "Links count should be right although linkEA overflow"
25058         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25059         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25060         [ $linkcount -eq 1001 ] ||
25061                 error "(5) Unexpected hard links count: $linkcount"
25062
25063         echo "List all links start at $(date)"
25064         ls -l $DIR/$tdir/foo > /dev/null ||
25065                 error "(6) Fail to list $DIR/$tdir/foo"
25066
25067         echo "Unlink hard links start at $(date)"
25068         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25069                 error "(7) Fail to unlink"
25070         echo "Unlink hard links finished at $(date)"
25071 }
25072 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25073
25074 test_410()
25075 {
25076         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25077                 skip "Need client version at least 2.9.59"
25078         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25079                 skip "Need MODULES build"
25080
25081         # Create a file, and stat it from the kernel
25082         local testfile=$DIR/$tfile
25083         touch $testfile
25084
25085         local run_id=$RANDOM
25086         local my_ino=$(stat --format "%i" $testfile)
25087
25088         # Try to insert the module. This will always fail as the
25089         # module is designed to not be inserted.
25090         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25091             &> /dev/null
25092
25093         # Anything but success is a test failure
25094         dmesg | grep -q \
25095             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25096             error "no inode match"
25097 }
25098 run_test 410 "Test inode number returned from kernel thread"
25099
25100 cleanup_test411_cgroup() {
25101         trap 0
25102         rmdir "$1"
25103 }
25104
25105 test_411() {
25106         local cg_basedir=/sys/fs/cgroup/memory
25107         # LU-9966
25108         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25109                 skip "no setup for cgroup"
25110
25111         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25112                 error "test file creation failed"
25113         cancel_lru_locks osc
25114
25115         # Create a very small memory cgroup to force a slab allocation error
25116         local cgdir=$cg_basedir/osc_slab_alloc
25117         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25118         trap "cleanup_test411_cgroup $cgdir" EXIT
25119         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25120         echo 1M > $cgdir/memory.limit_in_bytes
25121
25122         # Should not LBUG, just be killed by oom-killer
25123         # dd will return 0 even allocation failure in some environment.
25124         # So don't check return value
25125         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25126         cleanup_test411_cgroup $cgdir
25127
25128         return 0
25129 }
25130 run_test 411 "Slab allocation error with cgroup does not LBUG"
25131
25132 test_412() {
25133         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25134         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25135                 skip "Need server version at least 2.10.55"
25136
25137         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25138                 error "mkdir failed"
25139         $LFS getdirstripe $DIR/$tdir
25140         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25141         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25142                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25143         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25144         [ $stripe_count -eq 2 ] ||
25145                 error "expect 2 get $stripe_count"
25146
25147         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25148
25149         local index
25150         local index2
25151
25152         # subdirs should be on the same MDT as parent
25153         for i in $(seq 0 $((MDSCOUNT - 1))); do
25154                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25155                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25156                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25157                 (( index == i )) || error "mdt$i/sub on MDT$index"
25158         done
25159
25160         # stripe offset -1, ditto
25161         for i in {1..10}; do
25162                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25163                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25164                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25165                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25166                 (( index == index2 )) ||
25167                         error "qos$i on MDT$index, sub on MDT$index2"
25168         done
25169
25170         local testdir=$DIR/$tdir/inherit
25171
25172         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25173         # inherit 2 levels
25174         for i in 1 2; do
25175                 testdir=$testdir/s$i
25176                 mkdir $testdir || error "mkdir $testdir failed"
25177                 index=$($LFS getstripe -m $testdir)
25178                 (( index == 1 )) ||
25179                         error "$testdir on MDT$index"
25180         done
25181
25182         # not inherit any more
25183         testdir=$testdir/s3
25184         mkdir $testdir || error "mkdir $testdir failed"
25185         getfattr -d -m dmv $testdir | grep dmv &&
25186                 error "default LMV set on $testdir" || true
25187 }
25188 run_test 412 "mkdir on specific MDTs"
25189
25190 generate_uneven_mdts() {
25191         local threshold=$1
25192         local lmv_qos_maxage
25193         local lod_qos_maxage
25194         local ffree
25195         local bavail
25196         local max
25197         local min
25198         local max_index
25199         local min_index
25200         local tmp
25201         local i
25202
25203         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25204         $LCTL set_param lmv.*.qos_maxage=1
25205         stack_trap "$LCTL set_param \
25206                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25207         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25208                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25209         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25210                 lod.*.mdt_qos_maxage=1
25211         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25212                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25213
25214         echo
25215         echo "Check for uneven MDTs: "
25216
25217         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25218         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25219         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25220
25221         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25222         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25223         max_index=0
25224         min_index=0
25225         for ((i = 1; i < ${#ffree[@]}; i++)); do
25226                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25227                 if [ $tmp -gt $max ]; then
25228                         max=$tmp
25229                         max_index=$i
25230                 fi
25231                 if [ $tmp -lt $min ]; then
25232                         min=$tmp
25233                         min_index=$i
25234                 fi
25235         done
25236
25237         (( ${ffree[min_index]} > 0 )) ||
25238                 skip "no free files in MDT$min_index"
25239         (( ${ffree[min_index]} < 10000000 )) ||
25240                 skip "too many free files in MDT$min_index"
25241
25242         # Check if we need to generate uneven MDTs
25243         local diff=$(((max - min) * 100 / min))
25244         local testdir=$DIR/$tdir-fillmdt
25245         local start
25246
25247         mkdir -p $testdir
25248
25249         i=0
25250         while (( diff < threshold )); do
25251                 # generate uneven MDTs, create till $threshold% diff
25252                 echo -n "weight diff=$diff% must be > $threshold% ..."
25253                 echo "Fill MDT$min_index with 1000 files: loop $i"
25254                 testdir=$DIR/$tdir-fillmdt/$i
25255                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25256                         error "mkdir $testdir failed"
25257                 $LFS setstripe -E 1M -L mdt $testdir ||
25258                         error "setstripe $testdir failed"
25259                 start=$SECONDS
25260                 for F in f.{0..999}; do
25261                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25262                                 /dev/null 2>&1 || error "dd $F failed"
25263                 done
25264
25265                 # wait for QOS to update
25266                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25267
25268                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25269                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25270                 max=$(((${ffree[max_index]} >> 8) * \
25271                         (${bavail[max_index]} * bsize >> 16)))
25272                 min=$(((${ffree[min_index]} >> 8) * \
25273                         (${bavail[min_index]} * bsize >> 16)))
25274                 diff=$(((max - min) * 100 / min))
25275                 i=$((i + 1))
25276         done
25277
25278         echo "MDT filesfree available: ${ffree[@]}"
25279         echo "MDT blocks available: ${bavail[@]}"
25280         echo "weight diff=$diff%"
25281 }
25282
25283 test_qos_mkdir() {
25284         local mkdir_cmd=$1
25285         local stripe_count=$2
25286         local mdts=$(comma_list $(mdts_nodes))
25287
25288         local testdir
25289         local lmv_qos_prio_free
25290         local lmv_qos_threshold_rr
25291         local lmv_qos_maxage
25292         local lod_qos_prio_free
25293         local lod_qos_threshold_rr
25294         local lod_qos_maxage
25295         local count
25296         local i
25297
25298         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25299         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25300         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25301                 head -n1)
25302         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25303         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25304         stack_trap "$LCTL set_param \
25305                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25306         stack_trap "$LCTL set_param \
25307                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25308         stack_trap "$LCTL set_param \
25309                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25310
25311         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25312                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25313         lod_qos_prio_free=${lod_qos_prio_free%%%}
25314         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25315                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25316         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25317         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25318                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25319         stack_trap "do_nodes $mdts $LCTL set_param \
25320                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25321         stack_trap "do_nodes $mdts $LCTL set_param \
25322                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25323         stack_trap "do_nodes $mdts $LCTL set_param \
25324                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25325
25326         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25327         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25328
25329         testdir=$DIR/$tdir-s$stripe_count/rr
25330
25331         local stripe_index=$($LFS getstripe -m $testdir)
25332         local test_mkdir_rr=true
25333
25334         getfattr -d -m dmv -e hex $testdir | grep dmv
25335         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25336                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25337                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25338                         test_mkdir_rr=false
25339         fi
25340
25341         echo
25342         $test_mkdir_rr &&
25343                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25344                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25345
25346         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25347         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25348                 eval $mkdir_cmd $testdir/subdir$i ||
25349                         error "$mkdir_cmd subdir$i failed"
25350         done
25351
25352         for (( i = 0; i < $MDSCOUNT; i++ )); do
25353                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25354                 echo "$count directories created on MDT$i"
25355                 if $test_mkdir_rr; then
25356                         (( $count == 100 )) ||
25357                                 error "subdirs are not evenly distributed"
25358                 elif (( $i == $stripe_index )); then
25359                         (( $count == 100 * MDSCOUNT )) ||
25360                                 error "$count subdirs created on MDT$i"
25361                 else
25362                         (( $count == 0 )) ||
25363                                 error "$count subdirs created on MDT$i"
25364                 fi
25365
25366                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25367                         count=$($LFS getdirstripe $testdir/* |
25368                                 grep -c -P "^\s+$i\t")
25369                         echo "$count stripes created on MDT$i"
25370                         # deviation should < 5% of average
25371                         (( $count >= 95 * stripe_count &&
25372                            $count <= 105 * stripe_count)) ||
25373                                 error "stripes are not evenly distributed"
25374                 fi
25375         done
25376
25377         echo
25378         echo "Check for uneven MDTs: "
25379
25380         local ffree
25381         local bavail
25382         local max
25383         local min
25384         local max_index
25385         local min_index
25386         local tmp
25387
25388         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25389         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25390         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25391
25392         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25393         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25394         max_index=0
25395         min_index=0
25396         for ((i = 1; i < ${#ffree[@]}; i++)); do
25397                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25398                 if [ $tmp -gt $max ]; then
25399                         max=$tmp
25400                         max_index=$i
25401                 fi
25402                 if [ $tmp -lt $min ]; then
25403                         min=$tmp
25404                         min_index=$i
25405                 fi
25406         done
25407
25408         (( ${ffree[min_index]} > 0 )) ||
25409                 skip "no free files in MDT$min_index"
25410         (( ${ffree[min_index]} < 10000000 )) ||
25411                 skip "too many free files in MDT$min_index"
25412
25413         echo "MDT filesfree available: ${ffree[@]}"
25414         echo "MDT blocks available: ${bavail[@]}"
25415         echo "weight diff=$(((max - min) * 100 / min))%"
25416         echo
25417         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25418
25419         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25420         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25421         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25422         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25423         # decrease statfs age, so that it can be updated in time
25424         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25425         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25426
25427         sleep 1
25428
25429         testdir=$DIR/$tdir-s$stripe_count/qos
25430         local num=200
25431
25432         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25433         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25434                 eval $mkdir_cmd $testdir/subdir$i ||
25435                         error "$mkdir_cmd subdir$i failed"
25436         done
25437
25438         max=0
25439         for (( i = 0; i < $MDSCOUNT; i++ )); do
25440                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25441                 (( count > max )) && max=$count
25442                 echo "$count directories created on MDT$i"
25443         done
25444
25445         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25446
25447         # D-value should > 10% of averge
25448         (( max - min > num / 10 )) ||
25449                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25450
25451         # ditto for stripes
25452         if (( stripe_count > 1 )); then
25453                 max=0
25454                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25455                         count=$($LFS getdirstripe $testdir/* |
25456                                 grep -c -P "^\s+$i\t")
25457                         (( count > max )) && max=$count
25458                         echo "$count stripes created on MDT$i"
25459                 done
25460
25461                 min=$($LFS getdirstripe $testdir/* |
25462                         grep -c -P "^\s+$min_index\t")
25463                 (( max - min > num * stripe_count / 10 )) ||
25464                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25465         fi
25466 }
25467
25468 most_full_mdt() {
25469         local ffree
25470         local bavail
25471         local bsize
25472         local min
25473         local min_index
25474         local tmp
25475
25476         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25477         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25478         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25479
25480         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25481         min_index=0
25482         for ((i = 1; i < ${#ffree[@]}; i++)); do
25483                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25484                 (( tmp < min )) && min=$tmp && min_index=$i
25485         done
25486
25487         echo -n $min_index
25488 }
25489
25490 test_413a() {
25491         [ $MDSCOUNT -lt 2 ] &&
25492                 skip "We need at least 2 MDTs for this test"
25493
25494         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25495                 skip "Need server version at least 2.12.52"
25496
25497         local stripe_count
25498
25499         generate_uneven_mdts 100
25500         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25501                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25502                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25503                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25504                         error "mkdir failed"
25505                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25506         done
25507 }
25508 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25509
25510 test_413b() {
25511         [ $MDSCOUNT -lt 2 ] &&
25512                 skip "We need at least 2 MDTs for this test"
25513
25514         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25515                 skip "Need server version at least 2.12.52"
25516
25517         local testdir
25518         local stripe_count
25519
25520         generate_uneven_mdts 100
25521         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25522                 testdir=$DIR/$tdir-s$stripe_count
25523                 mkdir $testdir || error "mkdir $testdir failed"
25524                 mkdir $testdir/rr || error "mkdir rr failed"
25525                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25526                         error "mkdir qos failed"
25527                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25528                         $testdir/rr || error "setdirstripe rr failed"
25529                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25530                         error "setdirstripe failed"
25531                 test_qos_mkdir "mkdir" $stripe_count
25532         done
25533 }
25534 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25535
25536 test_413c() {
25537         (( $MDSCOUNT >= 2 )) ||
25538                 skip "We need at least 2 MDTs for this test"
25539
25540         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25541                 skip "Need server version at least 2.14.51"
25542
25543         local testdir
25544         local inherit
25545         local inherit_rr
25546
25547         testdir=$DIR/${tdir}-s1
25548         mkdir $testdir || error "mkdir $testdir failed"
25549         mkdir $testdir/rr || error "mkdir rr failed"
25550         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25551         # default max_inherit is -1, default max_inherit_rr is 0
25552         $LFS setdirstripe -D -c 1 $testdir/rr ||
25553                 error "setdirstripe rr failed"
25554         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25555                 error "setdirstripe qos failed"
25556         test_qos_mkdir "mkdir" 1
25557
25558         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25559         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25560         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25561         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25562         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25563
25564         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25565         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25566         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25567         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25568         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25569         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25570         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25571                 error "level2 shouldn't have default LMV" || true
25572 }
25573 run_test 413c "mkdir with default LMV max inherit rr"
25574
25575 test_413d() {
25576         (( MDSCOUNT >= 2 )) ||
25577                 skip "We need at least 2 MDTs for this test"
25578
25579         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25580                 skip "Need server version at least 2.14.51"
25581
25582         local lmv_qos_threshold_rr
25583
25584         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25585                 head -n1)
25586         stack_trap "$LCTL set_param \
25587                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25588
25589         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25590         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25591         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25592                 error "$tdir shouldn't have default LMV"
25593         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25594                 error "mkdir sub failed"
25595
25596         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25597
25598         (( count == 100 )) || error "$count subdirs on MDT0"
25599 }
25600 run_test 413d "inherit ROOT default LMV"
25601
25602 test_413e() {
25603         (( MDSCOUNT >= 2 )) ||
25604                 skip "We need at least 2 MDTs for this test"
25605         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25606                 skip "Need server version at least 2.14.55"
25607
25608         local testdir=$DIR/$tdir
25609         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25610         local max_inherit
25611         local sub_max_inherit
25612
25613         mkdir -p $testdir || error "failed to create $testdir"
25614
25615         # set default max-inherit to -1 if stripe count is 0 or 1
25616         $LFS setdirstripe -D -c 1 $testdir ||
25617                 error "failed to set default LMV"
25618         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25619         (( max_inherit == -1 )) ||
25620                 error "wrong max_inherit value $max_inherit"
25621
25622         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25623         $LFS setdirstripe -D -c -1 $testdir ||
25624                 error "failed to set default LMV"
25625         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25626         (( max_inherit > 0 )) ||
25627                 error "wrong max_inherit value $max_inherit"
25628
25629         # and the subdir will decrease the max_inherit by 1
25630         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25631         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25632         (( sub_max_inherit == max_inherit - 1)) ||
25633                 error "wrong max-inherit of subdir $sub_max_inherit"
25634
25635         # check specified --max-inherit and warning message
25636         stack_trap "rm -f $tmpfile"
25637         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25638                 error "failed to set default LMV"
25639         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25640         (( max_inherit == -1 )) ||
25641                 error "wrong max_inherit value $max_inherit"
25642
25643         # check the warning messages
25644         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25645                 error "failed to detect warning string"
25646         fi
25647 }
25648 run_test 413e "check default max-inherit value"
25649
25650 test_413z() {
25651         local pids=""
25652         local subdir
25653         local pid
25654
25655         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25656                 unlinkmany $subdir/f. 1000 &
25657                 pids="$pids $!"
25658         done
25659
25660         for pid in $pids; do
25661                 wait $pid
25662         done
25663 }
25664 run_test 413z "413 test cleanup"
25665
25666 test_414() {
25667 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25668         $LCTL set_param fail_loc=0x80000521
25669         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25670         rm -f $DIR/$tfile
25671 }
25672 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25673
25674 test_415() {
25675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25676         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25677                 skip "Need server version at least 2.11.52"
25678
25679         # LU-11102
25680         local total
25681         local setattr_pid
25682         local start_time
25683         local end_time
25684         local duration
25685
25686         total=500
25687         # this test may be slow on ZFS
25688         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25689
25690         # though this test is designed for striped directory, let's test normal
25691         # directory too since lock is always saved as CoS lock.
25692         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25693         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25694
25695         (
25696                 while true; do
25697                         touch $DIR/$tdir
25698                 done
25699         ) &
25700         setattr_pid=$!
25701
25702         start_time=$(date +%s)
25703         for i in $(seq $total); do
25704                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25705                         > /dev/null
25706         done
25707         end_time=$(date +%s)
25708         duration=$((end_time - start_time))
25709
25710         kill -9 $setattr_pid
25711
25712         echo "rename $total files took $duration sec"
25713         [ $duration -lt 100 ] || error "rename took $duration sec"
25714 }
25715 run_test 415 "lock revoke is not missing"
25716
25717 test_416() {
25718         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25719                 skip "Need server version at least 2.11.55"
25720
25721         # define OBD_FAIL_OSD_TXN_START    0x19a
25722         do_facet mds1 lctl set_param fail_loc=0x19a
25723
25724         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25725
25726         true
25727 }
25728 run_test 416 "transaction start failure won't cause system hung"
25729
25730 cleanup_417() {
25731         trap 0
25732         do_nodes $(comma_list $(mdts_nodes)) \
25733                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25734         do_nodes $(comma_list $(mdts_nodes)) \
25735                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25736         do_nodes $(comma_list $(mdts_nodes)) \
25737                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25738 }
25739
25740 test_417() {
25741         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25742         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25743                 skip "Need MDS version at least 2.11.56"
25744
25745         trap cleanup_417 RETURN EXIT
25746
25747         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25748         do_nodes $(comma_list $(mdts_nodes)) \
25749                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25750         $LFS migrate -m 0 $DIR/$tdir.1 &&
25751                 error "migrate dir $tdir.1 should fail"
25752
25753         do_nodes $(comma_list $(mdts_nodes)) \
25754                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25755         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25756                 error "create remote dir $tdir.2 should fail"
25757
25758         do_nodes $(comma_list $(mdts_nodes)) \
25759                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25760         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25761                 error "create striped dir $tdir.3 should fail"
25762         true
25763 }
25764 run_test 417 "disable remote dir, striped dir and dir migration"
25765
25766 # Checks that the outputs of df [-i] and lfs df [-i] match
25767 #
25768 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25769 check_lfs_df() {
25770         local dir=$2
25771         local inodes
25772         local df_out
25773         local lfs_df_out
25774         local count
25775         local passed=false
25776
25777         # blocks or inodes
25778         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25779
25780         for count in {1..100}; do
25781                 do_nodes "$CLIENTS" \
25782                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25783                 sync; sleep 0.2
25784
25785                 # read the lines of interest
25786                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25787                         error "df $inodes $dir | tail -n +2 failed"
25788                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25789                         error "lfs df $inodes $dir | grep summary: failed"
25790
25791                 # skip first substrings of each output as they are different
25792                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25793                 # compare the two outputs
25794                 passed=true
25795                 #  skip "available" on MDT until LU-13997 is fixed.
25796                 #for i in {1..5}; do
25797                 for i in 1 2 4 5; do
25798                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25799                 done
25800                 $passed && break
25801         done
25802
25803         if ! $passed; then
25804                 df -P $inodes $dir
25805                 echo
25806                 lfs df $inodes $dir
25807                 error "df and lfs df $1 output mismatch: "      \
25808                       "df ${inodes}: ${df_out[*]}, "            \
25809                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25810         fi
25811 }
25812
25813 test_418() {
25814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25815
25816         local dir=$DIR/$tdir
25817         local numfiles=$((RANDOM % 4096 + 2))
25818         local numblocks=$((RANDOM % 256 + 1))
25819
25820         wait_delete_completed
25821         test_mkdir $dir
25822
25823         # check block output
25824         check_lfs_df blocks $dir
25825         # check inode output
25826         check_lfs_df inodes $dir
25827
25828         # create a single file and retest
25829         echo "Creating a single file and testing"
25830         createmany -o $dir/$tfile- 1 &>/dev/null ||
25831                 error "creating 1 file in $dir failed"
25832         check_lfs_df blocks $dir
25833         check_lfs_df inodes $dir
25834
25835         # create a random number of files
25836         echo "Creating $((numfiles - 1)) files and testing"
25837         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25838                 error "creating $((numfiles - 1)) files in $dir failed"
25839
25840         # write a random number of blocks to the first test file
25841         echo "Writing $numblocks 4K blocks and testing"
25842         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25843                 count=$numblocks &>/dev/null ||
25844                 error "dd to $dir/${tfile}-0 failed"
25845
25846         # retest
25847         check_lfs_df blocks $dir
25848         check_lfs_df inodes $dir
25849
25850         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25851                 error "unlinking $numfiles files in $dir failed"
25852 }
25853 run_test 418 "df and lfs df outputs match"
25854
25855 test_419()
25856 {
25857         local dir=$DIR/$tdir
25858
25859         mkdir -p $dir
25860         touch $dir/file
25861
25862         cancel_lru_locks mdc
25863
25864         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25865         $LCTL set_param fail_loc=0x1410
25866         cat $dir/file
25867         $LCTL set_param fail_loc=0
25868         rm -rf $dir
25869 }
25870 run_test 419 "Verify open file by name doesn't crash kernel"
25871
25872 test_420()
25873 {
25874         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25875                 skip "Need MDS version at least 2.12.53"
25876
25877         local SAVE_UMASK=$(umask)
25878         local dir=$DIR/$tdir
25879         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25880
25881         mkdir -p $dir
25882         umask 0000
25883         mkdir -m03777 $dir/testdir
25884         ls -dn $dir/testdir
25885         # Need to remove trailing '.' when SELinux is enabled
25886         local dirperms=$(ls -dn $dir/testdir |
25887                          awk '{ sub(/\.$/, "", $1); print $1}')
25888         [ $dirperms == "drwxrwsrwt" ] ||
25889                 error "incorrect perms on $dir/testdir"
25890
25891         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25892                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25893         ls -n $dir/testdir/testfile
25894         local fileperms=$(ls -n $dir/testdir/testfile |
25895                           awk '{ sub(/\.$/, "", $1); print $1}')
25896         [ $fileperms == "-rwxr-xr-x" ] ||
25897                 error "incorrect perms on $dir/testdir/testfile"
25898
25899         umask $SAVE_UMASK
25900 }
25901 run_test 420 "clear SGID bit on non-directories for non-members"
25902
25903 test_421a() {
25904         local cnt
25905         local fid1
25906         local fid2
25907
25908         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25909                 skip "Need MDS version at least 2.12.54"
25910
25911         test_mkdir $DIR/$tdir
25912         createmany -o $DIR/$tdir/f 3
25913         cnt=$(ls -1 $DIR/$tdir | wc -l)
25914         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25915
25916         fid1=$(lfs path2fid $DIR/$tdir/f1)
25917         fid2=$(lfs path2fid $DIR/$tdir/f2)
25918         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25919
25920         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25921         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25922
25923         cnt=$(ls -1 $DIR/$tdir | wc -l)
25924         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25925
25926         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25927         createmany -o $DIR/$tdir/f 3
25928         cnt=$(ls -1 $DIR/$tdir | wc -l)
25929         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25930
25931         fid1=$(lfs path2fid $DIR/$tdir/f1)
25932         fid2=$(lfs path2fid $DIR/$tdir/f2)
25933         echo "remove using fsname $FSNAME"
25934         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25935
25936         cnt=$(ls -1 $DIR/$tdir | wc -l)
25937         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25938 }
25939 run_test 421a "simple rm by fid"
25940
25941 test_421b() {
25942         local cnt
25943         local FID1
25944         local FID2
25945
25946         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25947                 skip "Need MDS version at least 2.12.54"
25948
25949         test_mkdir $DIR/$tdir
25950         createmany -o $DIR/$tdir/f 3
25951         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25952         MULTIPID=$!
25953
25954         FID1=$(lfs path2fid $DIR/$tdir/f1)
25955         FID2=$(lfs path2fid $DIR/$tdir/f2)
25956         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25957
25958         kill -USR1 $MULTIPID
25959         wait
25960
25961         cnt=$(ls $DIR/$tdir | wc -l)
25962         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25963 }
25964 run_test 421b "rm by fid on open file"
25965
25966 test_421c() {
25967         local cnt
25968         local FIDS
25969
25970         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25971                 skip "Need MDS version at least 2.12.54"
25972
25973         test_mkdir $DIR/$tdir
25974         createmany -o $DIR/$tdir/f 3
25975         touch $DIR/$tdir/$tfile
25976         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25977         cnt=$(ls -1 $DIR/$tdir | wc -l)
25978         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25979
25980         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25981         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25982
25983         cnt=$(ls $DIR/$tdir | wc -l)
25984         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25985 }
25986 run_test 421c "rm by fid against hardlinked files"
25987
25988 test_421d() {
25989         local cnt
25990         local FIDS
25991
25992         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25993                 skip "Need MDS version at least 2.12.54"
25994
25995         test_mkdir $DIR/$tdir
25996         createmany -o $DIR/$tdir/f 4097
25997         cnt=$(ls -1 $DIR/$tdir | wc -l)
25998         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25999
26000         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26001         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26002
26003         cnt=$(ls $DIR/$tdir | wc -l)
26004         rm -rf $DIR/$tdir
26005         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26006 }
26007 run_test 421d "rmfid en masse"
26008
26009 test_421e() {
26010         local cnt
26011         local FID
26012
26013         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26014         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26015                 skip "Need MDS version at least 2.12.54"
26016
26017         mkdir -p $DIR/$tdir
26018         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26019         createmany -o $DIR/$tdir/striped_dir/f 512
26020         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26021         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26022
26023         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26024                 sed "s/[/][^:]*://g")
26025         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26026
26027         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26028         rm -rf $DIR/$tdir
26029         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26030 }
26031 run_test 421e "rmfid in DNE"
26032
26033 test_421f() {
26034         local cnt
26035         local FID
26036
26037         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26038                 skip "Need MDS version at least 2.12.54"
26039
26040         test_mkdir $DIR/$tdir
26041         touch $DIR/$tdir/f
26042         cnt=$(ls -1 $DIR/$tdir | wc -l)
26043         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26044
26045         FID=$(lfs path2fid $DIR/$tdir/f)
26046         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26047         # rmfid should fail
26048         cnt=$(ls -1 $DIR/$tdir | wc -l)
26049         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26050
26051         chmod a+rw $DIR/$tdir
26052         ls -la $DIR/$tdir
26053         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26054         # rmfid should fail
26055         cnt=$(ls -1 $DIR/$tdir | wc -l)
26056         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26057
26058         rm -f $DIR/$tdir/f
26059         $RUNAS touch $DIR/$tdir/f
26060         FID=$(lfs path2fid $DIR/$tdir/f)
26061         echo "rmfid as root"
26062         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26063         cnt=$(ls -1 $DIR/$tdir | wc -l)
26064         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26065
26066         rm -f $DIR/$tdir/f
26067         $RUNAS touch $DIR/$tdir/f
26068         cnt=$(ls -1 $DIR/$tdir | wc -l)
26069         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26070         FID=$(lfs path2fid $DIR/$tdir/f)
26071         # rmfid w/o user_fid2path mount option should fail
26072         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26073         cnt=$(ls -1 $DIR/$tdir | wc -l)
26074         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26075
26076         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26077         stack_trap "rmdir $tmpdir"
26078         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26079                 error "failed to mount client'"
26080         stack_trap "umount_client $tmpdir"
26081
26082         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26083         # rmfid should succeed
26084         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26085         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26086
26087         # rmfid shouldn't allow to remove files due to dir's permission
26088         chmod a+rwx $tmpdir/$tdir
26089         touch $tmpdir/$tdir/f
26090         ls -la $tmpdir/$tdir
26091         FID=$(lfs path2fid $tmpdir/$tdir/f)
26092         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26093         return 0
26094 }
26095 run_test 421f "rmfid checks permissions"
26096
26097 test_421g() {
26098         local cnt
26099         local FIDS
26100
26101         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26102         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26103                 skip "Need MDS version at least 2.12.54"
26104
26105         mkdir -p $DIR/$tdir
26106         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26107         createmany -o $DIR/$tdir/striped_dir/f 512
26108         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26109         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26110
26111         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26112                 sed "s/[/][^:]*://g")
26113
26114         rm -f $DIR/$tdir/striped_dir/f1*
26115         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26116         removed=$((512 - cnt))
26117
26118         # few files have been just removed, so we expect
26119         # rmfid to fail on their fids
26120         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26121         [ $removed != $errors ] && error "$errors != $removed"
26122
26123         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26124         rm -rf $DIR/$tdir
26125         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26126 }
26127 run_test 421g "rmfid to return errors properly"
26128
26129 test_422() {
26130         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26131         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26132         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26133         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26134         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26135
26136         local amc=$(at_max_get client)
26137         local amo=$(at_max_get mds1)
26138         local timeout=`lctl get_param -n timeout`
26139
26140         at_max_set 0 client
26141         at_max_set 0 mds1
26142
26143 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26144         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26145                         fail_val=$(((2*timeout + 10)*1000))
26146         touch $DIR/$tdir/d3/file &
26147         sleep 2
26148 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26149         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26150                         fail_val=$((2*timeout + 5))
26151         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26152         local pid=$!
26153         sleep 1
26154         kill -9 $pid
26155         sleep $((2 * timeout))
26156         echo kill $pid
26157         kill -9 $pid
26158         lctl mark touch
26159         touch $DIR/$tdir/d2/file3
26160         touch $DIR/$tdir/d2/file4
26161         touch $DIR/$tdir/d2/file5
26162
26163         wait
26164         at_max_set $amc client
26165         at_max_set $amo mds1
26166
26167         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26168         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26169                 error "Watchdog is always throttled"
26170 }
26171 run_test 422 "kill a process with RPC in progress"
26172
26173 stat_test() {
26174     df -h $MOUNT &
26175     df -h $MOUNT &
26176     df -h $MOUNT &
26177     df -h $MOUNT &
26178     df -h $MOUNT &
26179     df -h $MOUNT &
26180 }
26181
26182 test_423() {
26183     local _stats
26184     # ensure statfs cache is expired
26185     sleep 2;
26186
26187     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26188     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26189
26190     return 0
26191 }
26192 run_test 423 "statfs should return a right data"
26193
26194 test_424() {
26195 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26196         $LCTL set_param fail_loc=0x80000522
26197         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26198         rm -f $DIR/$tfile
26199 }
26200 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26201
26202 test_425() {
26203         test_mkdir -c -1 $DIR/$tdir
26204         $LFS setstripe -c -1 $DIR/$tdir
26205
26206         lru_resize_disable "" 100
26207         stack_trap "lru_resize_enable" EXIT
26208
26209         sleep 5
26210
26211         for i in $(seq $((MDSCOUNT * 125))); do
26212                 local t=$DIR/$tdir/$tfile_$i
26213
26214                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26215                         error_noexit "Create file $t"
26216         done
26217         stack_trap "rm -rf $DIR/$tdir" EXIT
26218
26219         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26220                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26221                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26222
26223                 [ $lock_count -le $lru_size ] ||
26224                         error "osc lock count $lock_count > lru size $lru_size"
26225         done
26226
26227         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26228                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26229                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26230
26231                 [ $lock_count -le $lru_size ] ||
26232                         error "mdc lock count $lock_count > lru size $lru_size"
26233         done
26234 }
26235 run_test 425 "lock count should not exceed lru size"
26236
26237 test_426() {
26238         splice-test -r $DIR/$tfile
26239         splice-test -rd $DIR/$tfile
26240         splice-test $DIR/$tfile
26241         splice-test -d $DIR/$tfile
26242 }
26243 run_test 426 "splice test on Lustre"
26244
26245 test_427() {
26246         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26247         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26248                 skip "Need MDS version at least 2.12.4"
26249         local log
26250
26251         mkdir $DIR/$tdir
26252         mkdir $DIR/$tdir/1
26253         mkdir $DIR/$tdir/2
26254         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26255         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26256
26257         $LFS getdirstripe $DIR/$tdir/1/dir
26258
26259         #first setfattr for creating updatelog
26260         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26261
26262 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26263         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26264         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26265         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26266
26267         sleep 2
26268         fail mds2
26269         wait_recovery_complete mds2 $((2*TIMEOUT))
26270
26271         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26272         echo $log | grep "get update log failed" &&
26273                 error "update log corruption is detected" || true
26274 }
26275 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26276
26277 test_428() {
26278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26279         local cache_limit=$CACHE_MAX
26280
26281         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26282         $LCTL set_param -n llite.*.max_cached_mb=64
26283
26284         mkdir $DIR/$tdir
26285         $LFS setstripe -c 1 $DIR/$tdir
26286         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26287         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26288         #test write
26289         for f in $(seq 4); do
26290                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26291         done
26292         wait
26293
26294         cancel_lru_locks osc
26295         # Test read
26296         for f in $(seq 4); do
26297                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26298         done
26299         wait
26300 }
26301 run_test 428 "large block size IO should not hang"
26302
26303 test_429() { # LU-7915 / LU-10948
26304         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26305         local testfile=$DIR/$tfile
26306         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26307         local new_flag=1
26308         local first_rpc
26309         local second_rpc
26310         local third_rpc
26311
26312         $LCTL get_param $ll_opencache_threshold_count ||
26313                 skip "client does not have opencache parameter"
26314
26315         set_opencache $new_flag
26316         stack_trap "restore_opencache"
26317         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26318                 error "enable opencache failed"
26319         touch $testfile
26320         # drop MDC DLM locks
26321         cancel_lru_locks mdc
26322         # clear MDC RPC stats counters
26323         $LCTL set_param $mdc_rpcstats=clear
26324
26325         # According to the current implementation, we need to run 3 times
26326         # open & close file to verify if opencache is enabled correctly.
26327         # 1st, RPCs are sent for lookup/open and open handle is released on
26328         #      close finally.
26329         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26330         #      so open handle won't be released thereafter.
26331         # 3rd, No RPC is sent out.
26332         $MULTIOP $testfile oc || error "multiop failed"
26333         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26334         echo "1st: $first_rpc RPCs in flight"
26335
26336         $MULTIOP $testfile oc || error "multiop failed"
26337         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26338         echo "2nd: $second_rpc RPCs in flight"
26339
26340         $MULTIOP $testfile oc || error "multiop failed"
26341         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26342         echo "3rd: $third_rpc RPCs in flight"
26343
26344         #verify no MDC RPC is sent
26345         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26346 }
26347 run_test 429 "verify if opencache flag on client side does work"
26348
26349 lseek_test_430() {
26350         local offset
26351         local file=$1
26352
26353         # data at [200K, 400K)
26354         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26355                 error "256K->512K dd fails"
26356         # data at [2M, 3M)
26357         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26358                 error "2M->3M dd fails"
26359         # data at [4M, 5M)
26360         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26361                 error "4M->5M dd fails"
26362         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26363         # start at first component hole #1
26364         printf "Seeking hole from 1000 ... "
26365         offset=$(lseek_test -l 1000 $file)
26366         echo $offset
26367         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26368         printf "Seeking data from 1000 ... "
26369         offset=$(lseek_test -d 1000 $file)
26370         echo $offset
26371         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26372
26373         # start at first component data block
26374         printf "Seeking hole from 300000 ... "
26375         offset=$(lseek_test -l 300000 $file)
26376         echo $offset
26377         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26378         printf "Seeking data from 300000 ... "
26379         offset=$(lseek_test -d 300000 $file)
26380         echo $offset
26381         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26382
26383         # start at the first component but beyond end of object size
26384         printf "Seeking hole from 1000000 ... "
26385         offset=$(lseek_test -l 1000000 $file)
26386         echo $offset
26387         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26388         printf "Seeking data from 1000000 ... "
26389         offset=$(lseek_test -d 1000000 $file)
26390         echo $offset
26391         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26392
26393         # start at second component stripe 2 (empty file)
26394         printf "Seeking hole from 1500000 ... "
26395         offset=$(lseek_test -l 1500000 $file)
26396         echo $offset
26397         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26398         printf "Seeking data from 1500000 ... "
26399         offset=$(lseek_test -d 1500000 $file)
26400         echo $offset
26401         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26402
26403         # start at second component stripe 1 (all data)
26404         printf "Seeking hole from 3000000 ... "
26405         offset=$(lseek_test -l 3000000 $file)
26406         echo $offset
26407         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26408         printf "Seeking data from 3000000 ... "
26409         offset=$(lseek_test -d 3000000 $file)
26410         echo $offset
26411         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26412
26413         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26414                 error "2nd dd fails"
26415         echo "Add data block at 640K...1280K"
26416
26417         # start at before new data block, in hole
26418         printf "Seeking hole from 600000 ... "
26419         offset=$(lseek_test -l 600000 $file)
26420         echo $offset
26421         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26422         printf "Seeking data from 600000 ... "
26423         offset=$(lseek_test -d 600000 $file)
26424         echo $offset
26425         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26426
26427         # start at the first component new data block
26428         printf "Seeking hole from 1000000 ... "
26429         offset=$(lseek_test -l 1000000 $file)
26430         echo $offset
26431         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26432         printf "Seeking data from 1000000 ... "
26433         offset=$(lseek_test -d 1000000 $file)
26434         echo $offset
26435         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26436
26437         # start at second component stripe 2, new data
26438         printf "Seeking hole from 1200000 ... "
26439         offset=$(lseek_test -l 1200000 $file)
26440         echo $offset
26441         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26442         printf "Seeking data from 1200000 ... "
26443         offset=$(lseek_test -d 1200000 $file)
26444         echo $offset
26445         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26446
26447         # start beyond file end
26448         printf "Using offset > filesize ... "
26449         lseek_test -l 4000000 $file && error "lseek should fail"
26450         printf "Using offset > filesize ... "
26451         lseek_test -d 4000000 $file && error "lseek should fail"
26452
26453         printf "Done\n\n"
26454 }
26455
26456 test_430a() {
26457         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26458                 skip "MDT does not support SEEK_HOLE"
26459
26460         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26461                 skip "OST does not support SEEK_HOLE"
26462
26463         local file=$DIR/$tdir/$tfile
26464
26465         mkdir -p $DIR/$tdir
26466
26467         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26468         # OST stripe #1 will have continuous data at [1M, 3M)
26469         # OST stripe #2 is empty
26470         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26471         lseek_test_430 $file
26472         rm $file
26473         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26474         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26475         lseek_test_430 $file
26476         rm $file
26477         $LFS setstripe -c2 -S 512K $file
26478         echo "Two stripes, stripe size 512K"
26479         lseek_test_430 $file
26480         rm $file
26481         # FLR with stale mirror
26482         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26483                        -N -c2 -S 1M $file
26484         echo "Mirrored file:"
26485         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26486         echo "Plain 2 stripes 1M"
26487         lseek_test_430 $file
26488         rm $file
26489 }
26490 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26491
26492 test_430b() {
26493         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26494                 skip "OST does not support SEEK_HOLE"
26495
26496         local offset
26497         local file=$DIR/$tdir/$tfile
26498
26499         mkdir -p $DIR/$tdir
26500         # Empty layout lseek should fail
26501         $MCREATE $file
26502         # seek from 0
26503         printf "Seeking hole from 0 ... "
26504         lseek_test -l 0 $file && error "lseek should fail"
26505         printf "Seeking data from 0 ... "
26506         lseek_test -d 0 $file && error "lseek should fail"
26507         rm $file
26508
26509         # 1M-hole file
26510         $LFS setstripe -E 1M -c2 -E eof $file
26511         $TRUNCATE $file 1048576
26512         printf "Seeking hole from 1000000 ... "
26513         offset=$(lseek_test -l 1000000 $file)
26514         echo $offset
26515         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26516         printf "Seeking data from 1000000 ... "
26517         lseek_test -d 1000000 $file && error "lseek should fail"
26518         rm $file
26519
26520         # full component followed by non-inited one
26521         $LFS setstripe -E 1M -c2 -E eof $file
26522         dd if=/dev/urandom of=$file bs=1M count=1
26523         printf "Seeking hole from 1000000 ... "
26524         offset=$(lseek_test -l 1000000 $file)
26525         echo $offset
26526         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26527         printf "Seeking hole from 1048576 ... "
26528         lseek_test -l 1048576 $file && error "lseek should fail"
26529         # init second component and truncate back
26530         echo "123" >> $file
26531         $TRUNCATE $file 1048576
26532         printf "Seeking hole from 1000000 ... "
26533         offset=$(lseek_test -l 1000000 $file)
26534         echo $offset
26535         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26536         printf "Seeking hole from 1048576 ... "
26537         lseek_test -l 1048576 $file && error "lseek should fail"
26538         # boundary checks for big values
26539         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26540         offset=$(lseek_test -d 0 $file.10g)
26541         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26542         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26543         offset=$(lseek_test -d 0 $file.100g)
26544         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26545         return 0
26546 }
26547 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26548
26549 test_430c() {
26550         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26551                 skip "OST does not support SEEK_HOLE"
26552
26553         local file=$DIR/$tdir/$tfile
26554         local start
26555
26556         mkdir -p $DIR/$tdir
26557         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26558
26559         # cp version 8.33+ prefers lseek over fiemap
26560         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26561                 start=$SECONDS
26562                 time cp $file /dev/null
26563                 (( SECONDS - start < 5 )) ||
26564                         error "cp: too long runtime $((SECONDS - start))"
26565
26566         fi
26567         # tar version 1.29+ supports SEEK_HOLE/DATA
26568         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26569                 start=$SECONDS
26570                 time tar cS $file - | cat > /dev/null
26571                 (( SECONDS - start < 5 )) ||
26572                         error "tar: too long runtime $((SECONDS - start))"
26573         fi
26574 }
26575 run_test 430c "lseek: external tools check"
26576
26577 test_431() { # LU-14187
26578         local file=$DIR/$tdir/$tfile
26579
26580         mkdir -p $DIR/$tdir
26581         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26582         dd if=/dev/urandom of=$file bs=4k count=1
26583         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26584         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26585         #define OBD_FAIL_OST_RESTART_IO 0x251
26586         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26587         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26588         cp $file $file.0
26589         cancel_lru_locks
26590         sync_all_data
26591         echo 3 > /proc/sys/vm/drop_caches
26592         diff  $file $file.0 || error "data diff"
26593 }
26594 run_test 431 "Restart transaction for IO"
26595
26596 cleanup_test_432() {
26597         do_facet mgs $LCTL nodemap_activate 0
26598         wait_nm_sync active
26599 }
26600
26601 test_432() {
26602         local tmpdir=$TMP/dir432
26603
26604         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26605                 skip "Need MDS version at least 2.14.52"
26606
26607         stack_trap cleanup_test_432 EXIT
26608         mkdir $DIR/$tdir
26609         mkdir $tmpdir
26610
26611         do_facet mgs $LCTL nodemap_activate 1
26612         wait_nm_sync active
26613         do_facet mgs $LCTL nodemap_modify --name default \
26614                 --property admin --value 1
26615         do_facet mgs $LCTL nodemap_modify --name default \
26616                 --property trusted --value 1
26617         cancel_lru_locks mdc
26618         wait_nm_sync default admin_nodemap
26619         wait_nm_sync default trusted_nodemap
26620
26621         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26622                grep -ci "Operation not permitted") -ne 0 ]; then
26623                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26624         fi
26625 }
26626 run_test 432 "mv dir from outside Lustre"
26627
26628 prep_801() {
26629         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26630         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26631                 skip "Need server version at least 2.9.55"
26632
26633         start_full_debug_logging
26634 }
26635
26636 post_801() {
26637         stop_full_debug_logging
26638 }
26639
26640 barrier_stat() {
26641         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26642                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26643                            awk '/The barrier for/ { print $7 }')
26644                 echo $st
26645         else
26646                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26647                 echo \'$st\'
26648         fi
26649 }
26650
26651 barrier_expired() {
26652         local expired
26653
26654         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26655                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26656                           awk '/will be expired/ { print $7 }')
26657         else
26658                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26659         fi
26660
26661         echo $expired
26662 }
26663
26664 test_801a() {
26665         prep_801
26666
26667         echo "Start barrier_freeze at: $(date)"
26668         #define OBD_FAIL_BARRIER_DELAY          0x2202
26669         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26670         # Do not reduce barrier time - See LU-11873
26671         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26672
26673         sleep 2
26674         local b_status=$(barrier_stat)
26675         echo "Got barrier status at: $(date)"
26676         [ "$b_status" = "'freezing_p1'" ] ||
26677                 error "(1) unexpected barrier status $b_status"
26678
26679         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26680         wait
26681         b_status=$(barrier_stat)
26682         [ "$b_status" = "'frozen'" ] ||
26683                 error "(2) unexpected barrier status $b_status"
26684
26685         local expired=$(barrier_expired)
26686         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26687         sleep $((expired + 3))
26688
26689         b_status=$(barrier_stat)
26690         [ "$b_status" = "'expired'" ] ||
26691                 error "(3) unexpected barrier status $b_status"
26692
26693         # Do not reduce barrier time - See LU-11873
26694         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26695                 error "(4) fail to freeze barrier"
26696
26697         b_status=$(barrier_stat)
26698         [ "$b_status" = "'frozen'" ] ||
26699                 error "(5) unexpected barrier status $b_status"
26700
26701         echo "Start barrier_thaw at: $(date)"
26702         #define OBD_FAIL_BARRIER_DELAY          0x2202
26703         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26704         do_facet mgs $LCTL barrier_thaw $FSNAME &
26705
26706         sleep 2
26707         b_status=$(barrier_stat)
26708         echo "Got barrier status at: $(date)"
26709         [ "$b_status" = "'thawing'" ] ||
26710                 error "(6) unexpected barrier status $b_status"
26711
26712         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26713         wait
26714         b_status=$(barrier_stat)
26715         [ "$b_status" = "'thawed'" ] ||
26716                 error "(7) unexpected barrier status $b_status"
26717
26718         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26719         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26720         do_facet mgs $LCTL barrier_freeze $FSNAME
26721
26722         b_status=$(barrier_stat)
26723         [ "$b_status" = "'failed'" ] ||
26724                 error "(8) unexpected barrier status $b_status"
26725
26726         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26727         do_facet mgs $LCTL barrier_thaw $FSNAME
26728
26729         post_801
26730 }
26731 run_test 801a "write barrier user interfaces and stat machine"
26732
26733 test_801b() {
26734         prep_801
26735
26736         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26737         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26738         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26739         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26740         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26741
26742         cancel_lru_locks mdc
26743
26744         # 180 seconds should be long enough
26745         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26746
26747         local b_status=$(barrier_stat)
26748         [ "$b_status" = "'frozen'" ] ||
26749                 error "(6) unexpected barrier status $b_status"
26750
26751         mkdir $DIR/$tdir/d0/d10 &
26752         mkdir_pid=$!
26753
26754         touch $DIR/$tdir/d1/f13 &
26755         touch_pid=$!
26756
26757         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26758         ln_pid=$!
26759
26760         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26761         mv_pid=$!
26762
26763         rm -f $DIR/$tdir/d4/f12 &
26764         rm_pid=$!
26765
26766         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26767
26768         # To guarantee taht the 'stat' is not blocked
26769         b_status=$(barrier_stat)
26770         [ "$b_status" = "'frozen'" ] ||
26771                 error "(8) unexpected barrier status $b_status"
26772
26773         # let above commands to run at background
26774         sleep 5
26775
26776         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26777         ps -p $touch_pid || error "(10) touch should be blocked"
26778         ps -p $ln_pid || error "(11) link should be blocked"
26779         ps -p $mv_pid || error "(12) rename should be blocked"
26780         ps -p $rm_pid || error "(13) unlink should be blocked"
26781
26782         b_status=$(barrier_stat)
26783         [ "$b_status" = "'frozen'" ] ||
26784                 error "(14) unexpected barrier status $b_status"
26785
26786         do_facet mgs $LCTL barrier_thaw $FSNAME
26787         b_status=$(barrier_stat)
26788         [ "$b_status" = "'thawed'" ] ||
26789                 error "(15) unexpected barrier status $b_status"
26790
26791         wait $mkdir_pid || error "(16) mkdir should succeed"
26792         wait $touch_pid || error "(17) touch should succeed"
26793         wait $ln_pid || error "(18) link should succeed"
26794         wait $mv_pid || error "(19) rename should succeed"
26795         wait $rm_pid || error "(20) unlink should succeed"
26796
26797         post_801
26798 }
26799 run_test 801b "modification will be blocked by write barrier"
26800
26801 test_801c() {
26802         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26803
26804         prep_801
26805
26806         stop mds2 || error "(1) Fail to stop mds2"
26807
26808         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26809
26810         local b_status=$(barrier_stat)
26811         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26812                 do_facet mgs $LCTL barrier_thaw $FSNAME
26813                 error "(2) unexpected barrier status $b_status"
26814         }
26815
26816         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26817                 error "(3) Fail to rescan barrier bitmap"
26818
26819         # Do not reduce barrier time - See LU-11873
26820         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26821
26822         b_status=$(barrier_stat)
26823         [ "$b_status" = "'frozen'" ] ||
26824                 error "(4) unexpected barrier status $b_status"
26825
26826         do_facet mgs $LCTL barrier_thaw $FSNAME
26827         b_status=$(barrier_stat)
26828         [ "$b_status" = "'thawed'" ] ||
26829                 error "(5) unexpected barrier status $b_status"
26830
26831         local devname=$(mdsdevname 2)
26832
26833         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26834
26835         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26836                 error "(7) Fail to rescan barrier bitmap"
26837
26838         post_801
26839 }
26840 run_test 801c "rescan barrier bitmap"
26841
26842 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26843 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26844 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26845 saved_MOUNT_OPTS=$MOUNT_OPTS
26846
26847 cleanup_802a() {
26848         trap 0
26849
26850         stopall
26851         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26852         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26853         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26854         MOUNT_OPTS=$saved_MOUNT_OPTS
26855         setupall
26856 }
26857
26858 test_802a() {
26859         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26860         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26861         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26862                 skip "Need server version at least 2.9.55"
26863
26864         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26865
26866         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26867
26868         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26869                 error "(2) Fail to copy"
26870
26871         trap cleanup_802a EXIT
26872
26873         # sync by force before remount as readonly
26874         sync; sync_all_data; sleep 3; sync_all_data
26875
26876         stopall
26877
26878         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26879         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26880         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26881
26882         echo "Mount the server as read only"
26883         setupall server_only || error "(3) Fail to start servers"
26884
26885         echo "Mount client without ro should fail"
26886         mount_client $MOUNT &&
26887                 error "(4) Mount client without 'ro' should fail"
26888
26889         echo "Mount client with ro should succeed"
26890         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26891         mount_client $MOUNT ||
26892                 error "(5) Mount client with 'ro' should succeed"
26893
26894         echo "Modify should be refused"
26895         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26896
26897         echo "Read should be allowed"
26898         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26899                 error "(7) Read should succeed under ro mode"
26900
26901         cleanup_802a
26902 }
26903 run_test 802a "simulate readonly device"
26904
26905 test_802b() {
26906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26907         remote_mds_nodsh && skip "remote MDS with nodsh"
26908
26909         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26910                 skip "readonly option not available"
26911
26912         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26913
26914         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26915                 error "(2) Fail to copy"
26916
26917         # write back all cached data before setting MDT to readonly
26918         cancel_lru_locks
26919         sync_all_data
26920
26921         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26922         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26923
26924         echo "Modify should be refused"
26925         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26926
26927         echo "Read should be allowed"
26928         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26929                 error "(7) Read should succeed under ro mode"
26930
26931         # disable readonly
26932         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26933 }
26934 run_test 802b "be able to set MDTs to readonly"
26935
26936 test_803a() {
26937         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26938         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26939                 skip "MDS needs to be newer than 2.10.54"
26940
26941         mkdir_on_mdt0 $DIR/$tdir
26942         # Create some objects on all MDTs to trigger related logs objects
26943         for idx in $(seq $MDSCOUNT); do
26944                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26945                         $DIR/$tdir/dir${idx} ||
26946                         error "Fail to create $DIR/$tdir/dir${idx}"
26947         done
26948
26949         sync; sleep 3
26950         wait_delete_completed # ensure old test cleanups are finished
26951         echo "before create:"
26952         $LFS df -i $MOUNT
26953         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26954
26955         for i in {1..10}; do
26956                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26957                         error "Fail to create $DIR/$tdir/foo$i"
26958         done
26959
26960         sync; sleep 3
26961         echo "after create:"
26962         $LFS df -i $MOUNT
26963         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26964
26965         # allow for an llog to be cleaned up during the test
26966         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26967                 error "before ($before_used) + 10 > after ($after_used)"
26968
26969         for i in {1..10}; do
26970                 rm -rf $DIR/$tdir/foo$i ||
26971                         error "Fail to remove $DIR/$tdir/foo$i"
26972         done
26973
26974         sleep 3 # avoid MDT return cached statfs
26975         wait_delete_completed
26976         echo "after unlink:"
26977         $LFS df -i $MOUNT
26978         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26979
26980         # allow for an llog to be created during the test
26981         [ $after_used -le $((before_used + 1)) ] ||
26982                 error "after ($after_used) > before ($before_used) + 1"
26983 }
26984 run_test 803a "verify agent object for remote object"
26985
26986 test_803b() {
26987         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26988         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26989                 skip "MDS needs to be newer than 2.13.56"
26990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26991
26992         for i in $(seq 0 $((MDSCOUNT - 1))); do
26993                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26994         done
26995
26996         local before=0
26997         local after=0
26998
26999         local tmp
27000
27001         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27002         for i in $(seq 0 $((MDSCOUNT - 1))); do
27003                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27004                         awk '/getattr/ { print $2 }')
27005                 before=$((before + tmp))
27006         done
27007         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27008         for i in $(seq 0 $((MDSCOUNT - 1))); do
27009                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27010                         awk '/getattr/ { print $2 }')
27011                 after=$((after + tmp))
27012         done
27013
27014         [ $before -eq $after ] || error "getattr count $before != $after"
27015 }
27016 run_test 803b "remote object can getattr from cache"
27017
27018 test_804() {
27019         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27020         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27021                 skip "MDS needs to be newer than 2.10.54"
27022         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27023
27024         mkdir -p $DIR/$tdir
27025         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27026                 error "Fail to create $DIR/$tdir/dir0"
27027
27028         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27029         local dev=$(mdsdevname 2)
27030
27031         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27032                 grep ${fid} || error "NOT found agent entry for dir0"
27033
27034         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27035                 error "Fail to create $DIR/$tdir/dir1"
27036
27037         touch $DIR/$tdir/dir1/foo0 ||
27038                 error "Fail to create $DIR/$tdir/dir1/foo0"
27039         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27040         local rc=0
27041
27042         for idx in $(seq $MDSCOUNT); do
27043                 dev=$(mdsdevname $idx)
27044                 do_facet mds${idx} \
27045                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27046                         grep ${fid} && rc=$idx
27047         done
27048
27049         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27050                 error "Fail to rename foo0 to foo1"
27051         if [ $rc -eq 0 ]; then
27052                 for idx in $(seq $MDSCOUNT); do
27053                         dev=$(mdsdevname $idx)
27054                         do_facet mds${idx} \
27055                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27056                         grep ${fid} && rc=$idx
27057                 done
27058         fi
27059
27060         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27061                 error "Fail to rename foo1 to foo2"
27062         if [ $rc -eq 0 ]; then
27063                 for idx in $(seq $MDSCOUNT); do
27064                         dev=$(mdsdevname $idx)
27065                         do_facet mds${idx} \
27066                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27067                         grep ${fid} && rc=$idx
27068                 done
27069         fi
27070
27071         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27072
27073         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27074                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27075         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27076                 error "Fail to rename foo2 to foo0"
27077         unlink $DIR/$tdir/dir1/foo0 ||
27078                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27079         rm -rf $DIR/$tdir/dir0 ||
27080                 error "Fail to rm $DIR/$tdir/dir0"
27081
27082         for idx in $(seq $MDSCOUNT); do
27083                 dev=$(mdsdevname $idx)
27084                 rc=0
27085
27086                 stop mds${idx}
27087                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27088                         rc=$?
27089                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27090                         error "mount mds$idx failed"
27091                 df $MOUNT > /dev/null 2>&1
27092
27093                 # e2fsck should not return error
27094                 [ $rc -eq 0 ] ||
27095                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27096         done
27097 }
27098 run_test 804 "verify agent entry for remote entry"
27099
27100 cleanup_805() {
27101         do_facet $SINGLEMDS zfs set quota=$old $fsset
27102         unlinkmany $DIR/$tdir/f- 1000000
27103         trap 0
27104 }
27105
27106 test_805() {
27107         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27108         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27109         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27110                 skip "netfree not implemented before 0.7"
27111         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27112                 skip "Need MDS version at least 2.10.57"
27113
27114         local fsset
27115         local freekb
27116         local usedkb
27117         local old
27118         local quota
27119         local pref="osd-zfs.$FSNAME-MDT0000."
27120
27121         # limit available space on MDS dataset to meet nospace issue
27122         # quickly. then ZFS 0.7.2 can use reserved space if asked
27123         # properly (using netfree flag in osd_declare_destroy()
27124         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27125         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27126                 gawk '{print $3}')
27127         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27128         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27129         let "usedkb=usedkb-freekb"
27130         let "freekb=freekb/2"
27131         if let "freekb > 5000"; then
27132                 let "freekb=5000"
27133         fi
27134         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27135         trap cleanup_805 EXIT
27136         mkdir_on_mdt0 $DIR/$tdir
27137         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27138                 error "Can't set PFL layout"
27139         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27140         rm -rf $DIR/$tdir || error "not able to remove"
27141         do_facet $SINGLEMDS zfs set quota=$old $fsset
27142         trap 0
27143 }
27144 run_test 805 "ZFS can remove from full fs"
27145
27146 # Size-on-MDS test
27147 check_lsom_data()
27148 {
27149         local file=$1
27150         local expect=$(stat -c %s $file)
27151
27152         check_lsom_size $1 $expect
27153
27154         local blocks=$($LFS getsom -b $file)
27155         expect=$(stat -c %b $file)
27156         [[ $blocks == $expect ]] ||
27157                 error "$file expected blocks: $expect, got: $blocks"
27158 }
27159
27160 check_lsom_size()
27161 {
27162         local size
27163         local expect=$2
27164
27165         cancel_lru_locks mdc
27166
27167         size=$($LFS getsom -s $1)
27168         [[ $size == $expect ]] ||
27169                 error "$file expected size: $expect, got: $size"
27170 }
27171
27172 test_806() {
27173         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27174                 skip "Need MDS version at least 2.11.52"
27175
27176         local bs=1048576
27177
27178         touch $DIR/$tfile || error "touch $tfile failed"
27179
27180         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27181         save_lustre_params client "llite.*.xattr_cache" > $save
27182         lctl set_param llite.*.xattr_cache=0
27183         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27184
27185         # single-threaded write
27186         echo "Test SOM for single-threaded write"
27187         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27188                 error "write $tfile failed"
27189         check_lsom_size $DIR/$tfile $bs
27190
27191         local num=32
27192         local size=$(($num * $bs))
27193         local offset=0
27194         local i
27195
27196         echo "Test SOM for single client multi-threaded($num) write"
27197         $TRUNCATE $DIR/$tfile 0
27198         for ((i = 0; i < $num; i++)); do
27199                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27200                 local pids[$i]=$!
27201                 offset=$((offset + $bs))
27202         done
27203         for (( i=0; i < $num; i++ )); do
27204                 wait ${pids[$i]}
27205         done
27206         check_lsom_size $DIR/$tfile $size
27207
27208         $TRUNCATE $DIR/$tfile 0
27209         for ((i = 0; i < $num; i++)); do
27210                 offset=$((offset - $bs))
27211                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27212                 local pids[$i]=$!
27213         done
27214         for (( i=0; i < $num; i++ )); do
27215                 wait ${pids[$i]}
27216         done
27217         check_lsom_size $DIR/$tfile $size
27218
27219         # multi-client writes
27220         num=$(get_node_count ${CLIENTS//,/ })
27221         size=$(($num * $bs))
27222         offset=0
27223         i=0
27224
27225         echo "Test SOM for multi-client ($num) writes"
27226         $TRUNCATE $DIR/$tfile 0
27227         for client in ${CLIENTS//,/ }; do
27228                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27229                 local pids[$i]=$!
27230                 i=$((i + 1))
27231                 offset=$((offset + $bs))
27232         done
27233         for (( i=0; i < $num; i++ )); do
27234                 wait ${pids[$i]}
27235         done
27236         check_lsom_size $DIR/$tfile $offset
27237
27238         i=0
27239         $TRUNCATE $DIR/$tfile 0
27240         for client in ${CLIENTS//,/ }; do
27241                 offset=$((offset - $bs))
27242                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27243                 local pids[$i]=$!
27244                 i=$((i + 1))
27245         done
27246         for (( i=0; i < $num; i++ )); do
27247                 wait ${pids[$i]}
27248         done
27249         check_lsom_size $DIR/$tfile $size
27250
27251         # verify truncate
27252         echo "Test SOM for truncate"
27253         $TRUNCATE $DIR/$tfile 1048576
27254         check_lsom_size $DIR/$tfile 1048576
27255         $TRUNCATE $DIR/$tfile 1234
27256         check_lsom_size $DIR/$tfile 1234
27257
27258         # verify SOM blocks count
27259         echo "Verify SOM block count"
27260         $TRUNCATE $DIR/$tfile 0
27261         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27262                 error "failed to write file $tfile"
27263         check_lsom_data $DIR/$tfile
27264 }
27265 run_test 806 "Verify Lazy Size on MDS"
27266
27267 test_807() {
27268         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27269         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27270                 skip "Need MDS version at least 2.11.52"
27271
27272         # Registration step
27273         changelog_register || error "changelog_register failed"
27274         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27275         changelog_users $SINGLEMDS | grep -q $cl_user ||
27276                 error "User $cl_user not found in changelog_users"
27277
27278         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27279         save_lustre_params client "llite.*.xattr_cache" > $save
27280         lctl set_param llite.*.xattr_cache=0
27281         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27282
27283         rm -rf $DIR/$tdir || error "rm $tdir failed"
27284         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27285         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27286         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27287         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27288                 error "truncate $tdir/trunc failed"
27289
27290         local bs=1048576
27291         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27292                 error "write $tfile failed"
27293
27294         # multi-client wirtes
27295         local num=$(get_node_count ${CLIENTS//,/ })
27296         local offset=0
27297         local i=0
27298
27299         echo "Test SOM for multi-client ($num) writes"
27300         touch $DIR/$tfile || error "touch $tfile failed"
27301         $TRUNCATE $DIR/$tfile 0
27302         for client in ${CLIENTS//,/ }; do
27303                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27304                 local pids[$i]=$!
27305                 i=$((i + 1))
27306                 offset=$((offset + $bs))
27307         done
27308         for (( i=0; i < $num; i++ )); do
27309                 wait ${pids[$i]}
27310         done
27311
27312         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27313         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27314         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27315         check_lsom_data $DIR/$tdir/trunc
27316         check_lsom_data $DIR/$tdir/single_dd
27317         check_lsom_data $DIR/$tfile
27318
27319         rm -rf $DIR/$tdir
27320         # Deregistration step
27321         changelog_deregister || error "changelog_deregister failed"
27322 }
27323 run_test 807 "verify LSOM syncing tool"
27324
27325 check_som_nologged()
27326 {
27327         local lines=$($LFS changelog $FSNAME-MDT0000 |
27328                 grep 'x=trusted.som' | wc -l)
27329         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27330 }
27331
27332 test_808() {
27333         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27334                 skip "Need MDS version at least 2.11.55"
27335
27336         # Registration step
27337         changelog_register || error "changelog_register failed"
27338
27339         touch $DIR/$tfile || error "touch $tfile failed"
27340         check_som_nologged
27341
27342         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27343                 error "write $tfile failed"
27344         check_som_nologged
27345
27346         $TRUNCATE $DIR/$tfile 1234
27347         check_som_nologged
27348
27349         $TRUNCATE $DIR/$tfile 1048576
27350         check_som_nologged
27351
27352         # Deregistration step
27353         changelog_deregister || error "changelog_deregister failed"
27354 }
27355 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27356
27357 check_som_nodata()
27358 {
27359         $LFS getsom $1
27360         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27361 }
27362
27363 test_809() {
27364         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27365                 skip "Need MDS version at least 2.11.56"
27366
27367         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27368                 error "failed to create DoM-only file $DIR/$tfile"
27369         touch $DIR/$tfile || error "touch $tfile failed"
27370         check_som_nodata $DIR/$tfile
27371
27372         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27373                 error "write $tfile failed"
27374         check_som_nodata $DIR/$tfile
27375
27376         $TRUNCATE $DIR/$tfile 1234
27377         check_som_nodata $DIR/$tfile
27378
27379         $TRUNCATE $DIR/$tfile 4097
27380         check_som_nodata $DIR/$file
27381 }
27382 run_test 809 "Verify no SOM xattr store for DoM-only files"
27383
27384 test_810() {
27385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27386         $GSS && skip_env "could not run with gss"
27387         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27388                 skip "OST < 2.12.58 doesn't align checksum"
27389
27390         set_checksums 1
27391         stack_trap "set_checksums $ORIG_CSUM" EXIT
27392         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27393
27394         local csum
27395         local before
27396         local after
27397         for csum in $CKSUM_TYPES; do
27398                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27399                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27400                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27401                         eval set -- $i
27402                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27403                         before=$(md5sum $DIR/$tfile)
27404                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27405                         after=$(md5sum $DIR/$tfile)
27406                         [ "$before" == "$after" ] ||
27407                                 error "$csum: $before != $after bs=$1 seek=$2"
27408                 done
27409         done
27410 }
27411 run_test 810 "partial page writes on ZFS (LU-11663)"
27412
27413 test_812a() {
27414         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27415                 skip "OST < 2.12.51 doesn't support this fail_loc"
27416
27417         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27418         # ensure ost1 is connected
27419         stat $DIR/$tfile >/dev/null || error "can't stat"
27420         wait_osc_import_state client ost1 FULL
27421         # no locks, no reqs to let the connection idle
27422         cancel_lru_locks osc
27423
27424         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27425 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27426         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27427         wait_osc_import_state client ost1 CONNECTING
27428         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27429
27430         stat $DIR/$tfile >/dev/null || error "can't stat file"
27431 }
27432 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27433
27434 test_812b() { # LU-12378
27435         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27436                 skip "OST < 2.12.51 doesn't support this fail_loc"
27437
27438         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27439         # ensure ost1 is connected
27440         stat $DIR/$tfile >/dev/null || error "can't stat"
27441         wait_osc_import_state client ost1 FULL
27442         # no locks, no reqs to let the connection idle
27443         cancel_lru_locks osc
27444
27445         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27446 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27447         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27448         wait_osc_import_state client ost1 CONNECTING
27449         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27450
27451         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27452         wait_osc_import_state client ost1 IDLE
27453 }
27454 run_test 812b "do not drop no resend request for idle connect"
27455
27456 test_812c() {
27457         local old
27458
27459         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27460
27461         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27462         $LFS getstripe $DIR/$tfile
27463         $LCTL set_param osc.*.idle_timeout=10
27464         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27465         # ensure ost1 is connected
27466         stat $DIR/$tfile >/dev/null || error "can't stat"
27467         wait_osc_import_state client ost1 FULL
27468         # no locks, no reqs to let the connection idle
27469         cancel_lru_locks osc
27470
27471 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27472         $LCTL set_param fail_loc=0x80000533
27473         sleep 15
27474         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27475 }
27476 run_test 812c "idle import vs lock enqueue race"
27477
27478 test_813() {
27479         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27480         [ -z "$file_heat_sav" ] && skip "no file heat support"
27481
27482         local readsample
27483         local writesample
27484         local readbyte
27485         local writebyte
27486         local readsample1
27487         local writesample1
27488         local readbyte1
27489         local writebyte1
27490
27491         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27492         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27493
27494         $LCTL set_param -n llite.*.file_heat=1
27495         echo "Turn on file heat"
27496         echo "Period second: $period_second, Decay percentage: $decay_pct"
27497
27498         echo "QQQQ" > $DIR/$tfile
27499         echo "QQQQ" > $DIR/$tfile
27500         echo "QQQQ" > $DIR/$tfile
27501         cat $DIR/$tfile > /dev/null
27502         cat $DIR/$tfile > /dev/null
27503         cat $DIR/$tfile > /dev/null
27504         cat $DIR/$tfile > /dev/null
27505
27506         local out=$($LFS heat_get $DIR/$tfile)
27507
27508         $LFS heat_get $DIR/$tfile
27509         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27510         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27511         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27512         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27513
27514         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27515         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27516         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27517         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27518
27519         sleep $((period_second + 3))
27520         echo "Sleep $((period_second + 3)) seconds..."
27521         # The recursion formula to calculate the heat of the file f is as
27522         # follow:
27523         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27524         # Where Hi is the heat value in the period between time points i*I and
27525         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27526         # to the weight of Ci.
27527         out=$($LFS heat_get $DIR/$tfile)
27528         $LFS heat_get $DIR/$tfile
27529         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27530         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27531         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27532         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27533
27534         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27535                 error "read sample ($readsample) is wrong"
27536         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27537                 error "write sample ($writesample) is wrong"
27538         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27539                 error "read bytes ($readbyte) is wrong"
27540         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27541                 error "write bytes ($writebyte) is wrong"
27542
27543         echo "QQQQ" > $DIR/$tfile
27544         echo "QQQQ" > $DIR/$tfile
27545         echo "QQQQ" > $DIR/$tfile
27546         cat $DIR/$tfile > /dev/null
27547         cat $DIR/$tfile > /dev/null
27548         cat $DIR/$tfile > /dev/null
27549         cat $DIR/$tfile > /dev/null
27550
27551         sleep $((period_second + 3))
27552         echo "Sleep $((period_second + 3)) seconds..."
27553
27554         out=$($LFS heat_get $DIR/$tfile)
27555         $LFS heat_get $DIR/$tfile
27556         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27557         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27558         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27559         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27560
27561         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27562                 4 * $decay_pct) / 100") -eq 1 ] ||
27563                 error "read sample ($readsample1) is wrong"
27564         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27565                 3 * $decay_pct) / 100") -eq 1 ] ||
27566                 error "write sample ($writesample1) is wrong"
27567         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27568                 20 * $decay_pct) / 100") -eq 1 ] ||
27569                 error "read bytes ($readbyte1) is wrong"
27570         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27571                 15 * $decay_pct) / 100") -eq 1 ] ||
27572                 error "write bytes ($writebyte1) is wrong"
27573
27574         echo "Turn off file heat for the file $DIR/$tfile"
27575         $LFS heat_set -o $DIR/$tfile
27576
27577         echo "QQQQ" > $DIR/$tfile
27578         echo "QQQQ" > $DIR/$tfile
27579         echo "QQQQ" > $DIR/$tfile
27580         cat $DIR/$tfile > /dev/null
27581         cat $DIR/$tfile > /dev/null
27582         cat $DIR/$tfile > /dev/null
27583         cat $DIR/$tfile > /dev/null
27584
27585         out=$($LFS heat_get $DIR/$tfile)
27586         $LFS heat_get $DIR/$tfile
27587         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27588         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27589         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27590         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27591
27592         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27593         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27594         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27595         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27596
27597         echo "Trun on file heat for the file $DIR/$tfile"
27598         $LFS heat_set -O $DIR/$tfile
27599
27600         echo "QQQQ" > $DIR/$tfile
27601         echo "QQQQ" > $DIR/$tfile
27602         echo "QQQQ" > $DIR/$tfile
27603         cat $DIR/$tfile > /dev/null
27604         cat $DIR/$tfile > /dev/null
27605         cat $DIR/$tfile > /dev/null
27606         cat $DIR/$tfile > /dev/null
27607
27608         out=$($LFS heat_get $DIR/$tfile)
27609         $LFS heat_get $DIR/$tfile
27610         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27611         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27612         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27613         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27614
27615         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27616         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27617         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27618         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27619
27620         $LFS heat_set -c $DIR/$tfile
27621         $LCTL set_param -n llite.*.file_heat=0
27622         echo "Turn off file heat support for the Lustre filesystem"
27623
27624         echo "QQQQ" > $DIR/$tfile
27625         echo "QQQQ" > $DIR/$tfile
27626         echo "QQQQ" > $DIR/$tfile
27627         cat $DIR/$tfile > /dev/null
27628         cat $DIR/$tfile > /dev/null
27629         cat $DIR/$tfile > /dev/null
27630         cat $DIR/$tfile > /dev/null
27631
27632         out=$($LFS heat_get $DIR/$tfile)
27633         $LFS heat_get $DIR/$tfile
27634         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27635         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27636         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27637         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27638
27639         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27640         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27641         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27642         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27643
27644         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27645         rm -f $DIR/$tfile
27646 }
27647 run_test 813 "File heat verfication"
27648
27649 test_814()
27650 {
27651         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27652         echo -n y >> $DIR/$tfile
27653         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27654         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27655 }
27656 run_test 814 "sparse cp works as expected (LU-12361)"
27657
27658 test_815()
27659 {
27660         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27661         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27662 }
27663 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27664
27665 test_816() {
27666         local ost1_imp=$(get_osc_import_name client ost1)
27667         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27668                          cut -d'.' -f2)
27669
27670         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27671         # ensure ost1 is connected
27672
27673         stat $DIR/$tfile >/dev/null || error "can't stat"
27674         wait_osc_import_state client ost1 FULL
27675         # no locks, no reqs to let the connection idle
27676         cancel_lru_locks osc
27677         lru_resize_disable osc
27678         local before
27679         local now
27680         before=$($LCTL get_param -n \
27681                  ldlm.namespaces.$imp_name.lru_size)
27682
27683         wait_osc_import_state client ost1 IDLE
27684         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27685         now=$($LCTL get_param -n \
27686               ldlm.namespaces.$imp_name.lru_size)
27687         [ $before == $now ] || error "lru_size changed $before != $now"
27688 }
27689 run_test 816 "do not reset lru_resize on idle reconnect"
27690
27691 cleanup_817() {
27692         umount $tmpdir
27693         exportfs -u localhost:$DIR/nfsexp
27694         rm -rf $DIR/nfsexp
27695 }
27696
27697 test_817() {
27698         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27699
27700         mkdir -p $DIR/nfsexp
27701         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27702                 error "failed to export nfs"
27703
27704         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27705         stack_trap cleanup_817 EXIT
27706
27707         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27708                 error "failed to mount nfs to $tmpdir"
27709
27710         cp /bin/true $tmpdir
27711         $DIR/nfsexp/true || error "failed to execute 'true' command"
27712 }
27713 run_test 817 "nfsd won't cache write lock for exec file"
27714
27715 test_818() {
27716         test_mkdir -i0 -c1 $DIR/$tdir
27717         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27718         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27719         stop $SINGLEMDS
27720
27721         # restore osp-syn threads
27722         stack_trap "fail $SINGLEMDS"
27723
27724         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27725         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27726         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27727                 error "start $SINGLEMDS failed"
27728         rm -rf $DIR/$tdir
27729
27730         local testid=$(echo $TESTNAME | tr '_' ' ')
27731
27732         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27733                 grep "run LFSCK" || error "run LFSCK is not suggested"
27734 }
27735 run_test 818 "unlink with failed llog"
27736
27737 test_819a() {
27738         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27739         cancel_lru_locks osc
27740         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27741         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27742         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27743         rm -f $TDIR/$tfile
27744 }
27745 run_test 819a "too big niobuf in read"
27746
27747 test_819b() {
27748         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27749         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27750         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27751         cancel_lru_locks osc
27752         sleep 1
27753         rm -f $TDIR/$tfile
27754 }
27755 run_test 819b "too big niobuf in write"
27756
27757
27758 function test_820_start_ost() {
27759         sleep 5
27760
27761         for num in $(seq $OSTCOUNT); do
27762                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27763         done
27764 }
27765
27766 test_820() {
27767         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27768
27769         mkdir $DIR/$tdir
27770         umount_client $MOUNT || error "umount failed"
27771         for num in $(seq $OSTCOUNT); do
27772                 stop ost$num
27773         done
27774
27775         # mount client with no active OSTs
27776         # so that the client can't initialize max LOV EA size
27777         # from OSC notifications
27778         mount_client $MOUNT || error "mount failed"
27779         # delay OST starting to keep this 0 max EA size for a while
27780         test_820_start_ost &
27781
27782         # create a directory on MDS2
27783         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27784                 error "Failed to create directory"
27785         # open intent should update default EA size
27786         # see mdc_update_max_ea_from_body()
27787         # notice this is the very first RPC to MDS2
27788         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27789         ret=$?
27790         echo $out
27791         # With SSK, this situation can lead to -EPERM being returned.
27792         # In that case, simply retry.
27793         if [ $ret -ne 0 ] && $SHARED_KEY; then
27794                 if echo "$out" | grep -q "not permitted"; then
27795                         cp /etc/services $DIR/$tdir/mds2
27796                         ret=$?
27797                 fi
27798         fi
27799         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27800 }
27801 run_test 820 "update max EA from open intent"
27802
27803 test_822() {
27804         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27805
27806         save_lustre_params mds1 \
27807                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27808         do_facet $SINGLEMDS "$LCTL set_param -n \
27809                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27810         do_facet $SINGLEMDS "$LCTL set_param -n \
27811                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27812
27813         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27814         local maxage=$(do_facet mds1 $LCTL get_param -n \
27815                        osp.$FSNAME-OST0000*MDT0000.maxage)
27816         sleep $((maxage + 1))
27817
27818         #define OBD_FAIL_NET_ERROR_RPC          0x532
27819         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27820
27821         stack_trap "restore_lustre_params < $p; rm $p"
27822
27823         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27824                       osp.$FSNAME-OST0000*MDT0000.create_count")
27825         for i in $(seq 1 $count); do
27826                 touch $DIR/$tfile.${i} || error "touch failed"
27827         done
27828 }
27829 run_test 822 "test precreate failure"
27830
27831 test_823() {
27832         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27833         local OST_MAX_PRECREATE=20000
27834
27835         save_lustre_params mds1 \
27836                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27837         do_facet $SINGLEMDS "$LCTL set_param -n \
27838                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27839         do_facet $SINGLEMDS "$LCTL set_param -n \
27840                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27841
27842         stack_trap "restore_lustre_params < $p; rm $p"
27843
27844         do_facet $SINGLEMDS "$LCTL set_param -n \
27845                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27846
27847         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27848                       osp.$FSNAME-OST0000*MDT0000.create_count")
27849         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27850                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27851         local expect_count=$(((($max/2)/256) * 256))
27852
27853         log "setting create_count to 100200:"
27854         log " -result- count: $count with max: $max, expecting: $expect_count"
27855
27856         [[ $count -eq expect_count ]] ||
27857                 error "Create count not set to max precreate."
27858 }
27859 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27860
27861 test_831() {
27862         local sync_changes=$(do_facet $SINGLEMDS \
27863                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27864
27865         [ "$sync_changes" -gt 100 ] &&
27866                 skip "Sync changes $sync_changes > 100 already"
27867
27868         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27869
27870         $LFS mkdir -i 0 $DIR/$tdir
27871         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27872
27873         save_lustre_params mds1 \
27874                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27875         save_lustre_params mds1 \
27876                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27877
27878         do_facet mds1 "$LCTL set_param -n \
27879                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27880                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27881         stack_trap "restore_lustre_params < $p" EXIT
27882
27883         createmany -o $DIR/$tdir/f- 1000
27884         unlinkmany $DIR/$tdir/f- 1000 &
27885         local UNLINK_PID=$!
27886
27887         while sleep 1; do
27888                 sync_changes=$(do_facet mds1 \
27889                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27890                 # the check in the code is racy, fail the test
27891                 # if the value above the limit by 10.
27892                 [ $sync_changes -gt 110 ] && {
27893                         kill -2 $UNLINK_PID
27894                         wait
27895                         error "osp changes throttling failed, $sync_changes>110"
27896                 }
27897                 kill -0 $UNLINK_PID 2> /dev/null || break
27898         done
27899         wait
27900 }
27901 run_test 831 "throttling unlink/setattr queuing on OSP"
27902
27903 #
27904 # tests that do cleanup/setup should be run at the end
27905 #
27906
27907 test_900() {
27908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27909         local ls
27910
27911         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27912         $LCTL set_param fail_loc=0x903
27913
27914         cancel_lru_locks MGC
27915
27916         FAIL_ON_ERROR=true cleanup
27917         FAIL_ON_ERROR=true setup
27918 }
27919 run_test 900 "umount should not race with any mgc requeue thread"
27920
27921 # LUS-6253/LU-11185
27922 test_901() {
27923         local oldc
27924         local newc
27925         local olds
27926         local news
27927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27928
27929         # some get_param have a bug to handle dot in param name
27930         cancel_lru_locks MGC
27931         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27932         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27933         umount_client $MOUNT || error "umount failed"
27934         mount_client $MOUNT || error "mount failed"
27935         cancel_lru_locks MGC
27936         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27937         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27938
27939         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27940         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27941
27942         return 0
27943 }
27944 run_test 901 "don't leak a mgc lock on client umount"
27945
27946 # LU-13377
27947 test_902() {
27948         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27949                 skip "client does not have LU-13377 fix"
27950         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27951         $LCTL set_param fail_loc=0x1415
27952         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27953         cancel_lru_locks osc
27954         rm -f $DIR/$tfile
27955 }
27956 run_test 902 "test short write doesn't hang lustre"
27957
27958 # LU-14711
27959 test_903() {
27960         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27961         echo "blah" > $DIR/${tfile}-2
27962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27963         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27964         $LCTL set_param fail_loc=0x417 fail_val=20
27965
27966         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27967         sleep 1 # To start the destroy
27968         wait_destroy_complete 150 || error "Destroy taking too long"
27969         cat $DIR/$tfile > /dev/null || error "Evicted"
27970 }
27971 run_test 903 "Test long page discard does not cause evictions"
27972
27973 test_904() {
27974         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
27975         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
27976                 grep -q project || skip "skip project quota not supported"
27977
27978         local testfile="$DIR/$tdir/$tfile"
27979         local xattr="trusted.projid"
27980         local projid
27981
27982         mkdir -p $DIR/$tdir
27983         touch $testfile
27984         #should be hidden when projid is 0
27985         $LFS project -p 0 $testfile ||
27986                 error "set $testfile project id failed"
27987         getfattr -m - $testfile | grep $xattr &&
27988                 error "do not show trusted.projid with project ID 0"
27989
27990         #still can getxattr explicitly
27991         projid=$(getfattr -n $xattr $testfile |
27992                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
27993         [ $projid == "0" ] ||
27994                 error "projid expected 0 not $projid"
27995
27996         #set the projid via setxattr
27997         setfattr -n $xattr -v "1000" $testfile ||
27998                 error "setattr failed with $?"
27999         projid=($($LFS project $testfile))
28000         [ ${projid[0]} == "1000" ] ||
28001                 error "projid expected 1000 not $projid"
28002
28003         #check the new projid via getxattr
28004         $LFS project -p 1001 $testfile ||
28005                 error "set $testfile project id failed"
28006         projid=$(getfattr -n $xattr $testfile |
28007                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28008         [ $projid == "1001" ] ||
28009                 error "projid expected 1001 not $projid"
28010
28011         #try to set invalid projid
28012         setfattr -n $xattr -v "4294967295" $testfile &&
28013                 error "set invalid projid should fail"
28014
28015         #remove the xattr means setting projid to 0
28016         setfattr -x $xattr $testfile ||
28017                 error "setfattr failed with $?"
28018         projid=($($LFS project $testfile))
28019         [ ${projid[0]} == "0" ] ||
28020                 error "projid expected 0 not $projid"
28021
28022         #should be hidden when parent has inherit flag and same projid
28023         $LFS project -srp 1002 $DIR/$tdir ||
28024                 error "set $tdir project id failed"
28025         getfattr -m - $testfile | grep $xattr &&
28026                 error "do not show trusted.projid with inherit flag"
28027
28028         #still can getxattr explicitly
28029         projid=$(getfattr -n $xattr $testfile |
28030                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28031         [ $projid == "1002" ] ||
28032                 error "projid expected 1002 not $projid"
28033 }
28034 run_test 904 "virtual project ID xattr"
28035
28036 complete $SECONDS
28037 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28038 check_and_cleanup_lustre
28039 if [ "$I_MOUNTED" != "yes" ]; then
28040         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28041 fi
28042 exit_status