Whamcloud - gitweb
LU-13745 tests: skip sanity test_426 for 4.18+
[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-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
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-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip splice tests on kernels >= 4.18.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.18.0) ]; then
68         # bug number:   LU-14045
69         ALWAYS_EXCEPT+=" 426"
70 fi
71 # skip nfs tests on kernels >= 4.12.0 until they are fixed
72 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
73         # bug number:   LU-12661
74         ALWAYS_EXCEPT+=" 817"
75 fi
76 # skip cgroup tests on RHEL8.1 kernels until they are fixed
77 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
78       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
79         # bug number:   LU-13063
80         ALWAYS_EXCEPT+=" 411"
81 fi
82
83 #                                  5          12     8   12  (min)"
84 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
85
86 if [ "$mds1_FSTYPE" = "zfs" ]; then
87         # bug number for skipped test:
88         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
89         #                                               13    (min)"
90         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
91 fi
92
93 # Get the SLES distro version
94 #
95 # Returns a version string that should only be used in comparing
96 # strings returned by version_code()
97 sles_version_code()
98 {
99         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
100
101         # All SuSE Linux versions have one decimal. version_code expects two
102         local sles_version=$version.0
103         version_code $sles_version
104 }
105
106 # Check if we are running on Ubuntu or SLES so we can make decisions on
107 # what tests to run
108 if [ -r /etc/SuSE-release ]; then
109         sles_version=$(sles_version_code)
110         [ $sles_version -lt $(version_code 11.4.0) ] &&
111                 # bug number for skipped test: LU-4341
112                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
113         [ $sles_version -lt $(version_code 12.0.0) ] &&
114                 # bug number for skipped test: LU-3703
115                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
116 elif [ -r /etc/os-release ]; then
117         if grep -qi ubuntu /etc/os-release; then
118                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
119                                                 -e 's/^VERSION=//p' \
120                                                 /etc/os-release |
121                                                 awk '{ print $1 }'))
122
123                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
124                         # bug number for skipped test:
125                         #                LU-10334 LU-10366
126                         ALWAYS_EXCEPT+=" 103a     410"
127                 fi
128         fi
129 fi
130
131 build_test_filter
132 FAIL_ON_ERROR=false
133
134 cleanup() {
135         echo -n "cln.."
136         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
137         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
138 }
139 setup() {
140         echo -n "mnt.."
141         load_modules
142         setupall || exit 10
143         echo "done"
144 }
145
146 check_swap_layouts_support()
147 {
148         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
149                 skip "Does not support layout lock."
150 }
151
152 check_swap_layout_no_dom()
153 {
154         local FOLDER=$1
155         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
156         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
157 }
158
159 check_and_setup_lustre
160 DIR=${DIR:-$MOUNT}
161 assert_DIR
162
163 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
164
165 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
166 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
167 rm -rf $DIR/[Rdfs][0-9]*
168
169 # $RUNAS_ID may get set incorrectly somewhere else
170 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
171         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
172
173 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
174
175 if [ "${ONLY}" = "MOUNT" ] ; then
176         echo "Lustre is up, please go on"
177         exit
178 fi
179
180 echo "preparing for tests involving mounts"
181 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
182 touch $EXT2_DEV
183 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
184 echo # add a newline after mke2fs.
185
186 umask 077
187
188 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
189 lctl set_param debug=-1 2> /dev/null || true
190 test_0a() {
191         touch $DIR/$tfile
192         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
193         rm $DIR/$tfile
194         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
195 }
196 run_test 0a "touch; rm ====================="
197
198 test_0b() {
199         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
200         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
201 }
202 run_test 0b "chmod 0755 $DIR ============================="
203
204 test_0c() {
205         $LCTL get_param mdc.*.import | grep "state: FULL" ||
206                 error "import not FULL"
207         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
208                 error "bad target"
209 }
210 run_test 0c "check import proc"
211
212 test_0d() { # LU-3397
213         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
214                 skip "proc exports not supported before 2.10.57"
215
216         local mgs_exp="mgs.MGS.exports"
217         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
218         local exp_client_nid
219         local exp_client_version
220         local exp_val
221         local imp_val
222         local temp_imp=$DIR/$tfile.import
223         local temp_exp=$DIR/$tfile.export
224
225         # save mgc import file to $temp_imp
226         $LCTL get_param mgc.*.import | tee $temp_imp
227         # Check if client uuid is found in MGS export
228         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
229                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
230                         $client_uuid ] &&
231                         break;
232         done
233         # save mgs export file to $temp_exp
234         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
235
236         # Compare the value of field "connect_flags"
237         imp_val=$(grep "connect_flags" $temp_imp)
238         exp_val=$(grep "connect_flags" $temp_exp)
239         [ "$exp_val" == "$imp_val" ] ||
240                 error "export flags '$exp_val' != import flags '$imp_val'"
241
242         # Compare the value of client version
243         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
244         exp_val=$(version_code $exp_client_version)
245         imp_val=$CLIENT_VERSION
246         [ "$exp_val" == "$imp_val" ] ||
247                 error "export client version '$exp_val' != '$imp_val'"
248 }
249 run_test 0d "check export proc ============================="
250
251 test_1() {
252         test_mkdir $DIR/$tdir
253         test_mkdir $DIR/$tdir/d2
254         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
255         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
256         rmdir $DIR/$tdir/d2
257         rmdir $DIR/$tdir
258         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
259 }
260 run_test 1 "mkdir; remkdir; rmdir"
261
262 test_2() {
263         test_mkdir $DIR/$tdir
264         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
265         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
266         rm -r $DIR/$tdir
267         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
268 }
269 run_test 2 "mkdir; touch; rmdir; check file"
270
271 test_3() {
272         test_mkdir $DIR/$tdir
273         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
274         touch $DIR/$tdir/$tfile
275         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
276         rm -r $DIR/$tdir
277         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
278 }
279 run_test 3 "mkdir; touch; rmdir; check dir"
280
281 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
282 test_4() {
283         test_mkdir -i 1 $DIR/$tdir
284
285         touch $DIR/$tdir/$tfile ||
286                 error "Create file under remote directory failed"
287
288         rmdir $DIR/$tdir &&
289                 error "Expect error removing in-use dir $DIR/$tdir"
290
291         test -d $DIR/$tdir || error "Remote directory disappeared"
292
293         rm -rf $DIR/$tdir || error "remove remote dir error"
294 }
295 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
296
297 test_5() {
298         test_mkdir $DIR/$tdir
299         test_mkdir $DIR/$tdir/d2
300         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
301         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
302         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
303 }
304 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
305
306 test_6a() {
307         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
308         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
309         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
310                 error "$tfile does not have perm 0666 or UID $UID"
311         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile should be 0666 and owned by UID $UID"
314 }
315 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
316
317 test_6c() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by UID $RUNAS_ID"
324         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327 }
328 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
329
330 test_6e() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         touch $DIR/$tfile
334         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
335         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
336                 error "$tfile should be owned by GID $UID"
337         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
340 }
341 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
342
343 test_6g() {
344         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
345
346         test_mkdir $DIR/$tdir
347         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
348         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
349         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
350         test_mkdir $DIR/$tdir/d/subdir
351         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
352                 error "$tdir/d/subdir should be GID $RUNAS_GID"
353         if [[ $MDSCOUNT -gt 1 ]]; then
354                 # check remote dir sgid inherite
355                 $LFS mkdir -i 0 $DIR/$tdir.local ||
356                         error "mkdir $tdir.local failed"
357                 chmod g+s $DIR/$tdir.local ||
358                         error "chmod $tdir.local failed"
359                 chgrp $RUNAS_GID $DIR/$tdir.local ||
360                         error "chgrp $tdir.local failed"
361                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
362                         error "mkdir $tdir.remote failed"
363                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
364                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
365                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
366                         error "$tdir.remote should be mode 02755"
367         fi
368 }
369 run_test 6g "verify new dir in sgid dir inherits group"
370
371 test_6h() { # bug 7331
372         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
373
374         touch $DIR/$tfile || error "touch failed"
375         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
376         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
377                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
378         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
379                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
380 }
381 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
382
383 test_7a() {
384         test_mkdir $DIR/$tdir
385         $MCREATE $DIR/$tdir/$tfile
386         chmod 0666 $DIR/$tdir/$tfile
387         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
388                 error "$tdir/$tfile should be mode 0666"
389 }
390 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
391
392 test_7b() {
393         if [ ! -d $DIR/$tdir ]; then
394                 test_mkdir $DIR/$tdir
395         fi
396         $MCREATE $DIR/$tdir/$tfile
397         echo -n foo > $DIR/$tdir/$tfile
398         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
399         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
400 }
401 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
402
403 test_8() {
404         test_mkdir $DIR/$tdir
405         touch $DIR/$tdir/$tfile
406         chmod 0666 $DIR/$tdir/$tfile
407         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
408                 error "$tfile mode not 0666"
409 }
410 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
411
412 test_9() {
413         test_mkdir $DIR/$tdir
414         test_mkdir $DIR/$tdir/d2
415         test_mkdir $DIR/$tdir/d2/d3
416         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
417 }
418 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
419
420 test_10() {
421         test_mkdir $DIR/$tdir
422         test_mkdir $DIR/$tdir/d2
423         touch $DIR/$tdir/d2/$tfile
424         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
425                 error "$tdir/d2/$tfile not a file"
426 }
427 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
428
429 test_11() {
430         test_mkdir $DIR/$tdir
431         test_mkdir $DIR/$tdir/d2
432         chmod 0666 $DIR/$tdir/d2
433         chmod 0705 $DIR/$tdir/d2
434         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
435                 error "$tdir/d2 mode not 0705"
436 }
437 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
438
439 test_12() {
440         test_mkdir $DIR/$tdir
441         touch $DIR/$tdir/$tfile
442         chmod 0666 $DIR/$tdir/$tfile
443         chmod 0654 $DIR/$tdir/$tfile
444         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
445                 error "$tdir/d2 mode not 0654"
446 }
447 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
448
449 test_13() {
450         test_mkdir $DIR/$tdir
451         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
452         >  $DIR/$tdir/$tfile
453         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
454                 error "$tdir/$tfile size not 0 after truncate"
455 }
456 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
457
458 test_14() {
459         test_mkdir $DIR/$tdir
460         touch $DIR/$tdir/$tfile
461         rm $DIR/$tdir/$tfile
462         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
463 }
464 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
465
466 test_15() {
467         test_mkdir $DIR/$tdir
468         touch $DIR/$tdir/$tfile
469         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
470         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
471                 error "$tdir/${tfile_2} not a file after rename"
472         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
473 }
474 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
475
476 test_16() {
477         test_mkdir $DIR/$tdir
478         touch $DIR/$tdir/$tfile
479         rm -rf $DIR/$tdir/$tfile
480         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
481 }
482 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
483
484 test_17a() {
485         test_mkdir $DIR/$tdir
486         touch $DIR/$tdir/$tfile
487         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
490                 error "$tdir/l-exist not a symlink"
491         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
492                 error "$tdir/l-exist not referencing a file"
493         rm -f $DIR/$tdir/l-exist
494         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
495 }
496 run_test 17a "symlinks: create, remove (real)"
497
498 test_17b() {
499         test_mkdir $DIR/$tdir
500         ln -s no-such-file $DIR/$tdir/l-dangle
501         ls -l $DIR/$tdir
502         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
503                 error "$tdir/l-dangle not referencing no-such-file"
504         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
505                 error "$tdir/l-dangle not referencing non-existent file"
506         rm -f $DIR/$tdir/l-dangle
507         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
508 }
509 run_test 17b "symlinks: create, remove (dangling)"
510
511 test_17c() { # bug 3440 - don't save failed open RPC for replay
512         test_mkdir $DIR/$tdir
513         ln -s foo $DIR/$tdir/$tfile
514         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
515 }
516 run_test 17c "symlinks: open dangling (should return error)"
517
518 test_17d() {
519         test_mkdir $DIR/$tdir
520         ln -s foo $DIR/$tdir/$tfile
521         touch $DIR/$tdir/$tfile || error "creating to new symlink"
522 }
523 run_test 17d "symlinks: create dangling"
524
525 test_17e() {
526         test_mkdir $DIR/$tdir
527         local foo=$DIR/$tdir/$tfile
528         ln -s $foo $foo || error "create symlink failed"
529         ls -l $foo || error "ls -l failed"
530         ls $foo && error "ls not failed" || true
531 }
532 run_test 17e "symlinks: create recursive symlink (should return error)"
533
534 test_17f() {
535         test_mkdir $DIR/$tdir
536         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
537         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
538         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
539         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
541         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
542         ls -l  $DIR/$tdir
543 }
544 run_test 17f "symlinks: long and very long symlink name"
545
546 # str_repeat(S, N) generate a string that is string S repeated N times
547 str_repeat() {
548         local s=$1
549         local n=$2
550         local ret=''
551         while [ $((n -= 1)) -ge 0 ]; do
552                 ret=$ret$s
553         done
554         echo $ret
555 }
556
557 # Long symlinks and LU-2241
558 test_17g() {
559         test_mkdir $DIR/$tdir
560         local TESTS="59 60 61 4094 4095"
561
562         # Fix for inode size boundary in 2.1.4
563         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
564                 TESTS="4094 4095"
565
566         # Patch not applied to 2.2 or 2.3 branches
567         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
568         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
569                 TESTS="4094 4095"
570
571         for i in $TESTS; do
572                 local SYMNAME=$(str_repeat 'x' $i)
573                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
574                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
575         done
576 }
577 run_test 17g "symlinks: really long symlink name and inode boundaries"
578
579 test_17h() { #bug 17378
580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
581         remote_mds_nodsh && skip "remote MDS with nodsh"
582
583         local mdt_idx
584
585         test_mkdir $DIR/$tdir
586         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
587         $LFS setstripe -c -1 $DIR/$tdir
588         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
589         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
590         touch $DIR/$tdir/$tfile || true
591 }
592 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
593
594 test_17i() { #bug 20018
595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
596         remote_mds_nodsh && skip "remote MDS with nodsh"
597
598         local foo=$DIR/$tdir/$tfile
599         local mdt_idx
600
601         test_mkdir -c1 $DIR/$tdir
602         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
603         ln -s $foo $foo || error "create symlink failed"
604 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
605         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
606         ls -l $foo && error "error not detected"
607         return 0
608 }
609 run_test 17i "don't panic on short symlink (should return error)"
610
611 test_17k() { #bug 22301
612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
613         [[ -z "$(which rsync 2>/dev/null)" ]] &&
614                 skip "no rsync command"
615         rsync --help | grep -q xattr ||
616                 skip_env "$(rsync --version | head -n1) does not support xattrs"
617         test_mkdir $DIR/$tdir
618         test_mkdir $DIR/$tdir.new
619         touch $DIR/$tdir/$tfile
620         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
621         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
622                 error "rsync failed with xattrs enabled"
623 }
624 run_test 17k "symlinks: rsync with xattrs enabled"
625
626 test_17l() { # LU-279
627         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
628                 skip "no getfattr command"
629
630         test_mkdir $DIR/$tdir
631         touch $DIR/$tdir/$tfile
632         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
633         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
634                 # -h to not follow symlinks. -m '' to list all the xattrs.
635                 # grep to remove first line: '# file: $path'.
636                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
637                 do
638                         lgetxattr_size_check $path $xattr ||
639                                 error "lgetxattr_size_check $path $xattr failed"
640                 done
641         done
642 }
643 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
644
645 # LU-1540
646 test_17m() {
647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
648         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
649         remote_mds_nodsh && skip "remote MDS with nodsh"
650         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
651         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
652                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
653
654         local short_sym="0123456789"
655         local wdir=$DIR/$tdir
656         local i
657
658         test_mkdir $wdir
659         long_sym=$short_sym
660         # create a long symlink file
661         for ((i = 0; i < 4; ++i)); do
662                 long_sym=${long_sym}${long_sym}
663         done
664
665         echo "create 512 short and long symlink files under $wdir"
666         for ((i = 0; i < 256; ++i)); do
667                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
668                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
669         done
670
671         echo "erase them"
672         rm -f $wdir/*
673         sync
674         wait_delete_completed
675
676         echo "recreate the 512 symlink files with a shorter string"
677         for ((i = 0; i < 512; ++i)); do
678                 # rewrite the symlink file with a shorter string
679                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
680                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
681         done
682
683         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
684         local devname=$(mdsdevname $mds_index)
685
686         echo "stop and checking mds${mds_index}:"
687         # e2fsck should not return error
688         stop mds${mds_index}
689         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
690         rc=$?
691
692         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
693                 error "start mds${mds_index} failed"
694         df $MOUNT > /dev/null 2>&1
695         [ $rc -eq 0 ] ||
696                 error "e2fsck detected error for short/long symlink: rc=$rc"
697         rm -f $wdir/*
698 }
699 run_test 17m "run e2fsck against MDT which contains short/long symlink"
700
701 check_fs_consistency_17n() {
702         local mdt_index
703         local rc=0
704
705         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
706         # so it only check MDT1/MDT2 instead of all of MDTs.
707         for mdt_index in 1 2; do
708                 local devname=$(mdsdevname $mdt_index)
709                 # e2fsck should not return error
710                 stop mds${mdt_index}
711                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
712                         rc=$((rc + $?))
713
714                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
715                         error "mount mds$mdt_index failed"
716                 df $MOUNT > /dev/null 2>&1
717         done
718         return $rc
719 }
720
721 test_17n() {
722         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
724         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
725         remote_mds_nodsh && skip "remote MDS with nodsh"
726         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
727         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
728                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
729
730         local i
731
732         test_mkdir $DIR/$tdir
733         for ((i=0; i<10; i++)); do
734                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
735                         error "create remote dir error $i"
736                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
737                         error "create files under remote dir failed $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after create files under remote dir"
742
743         for ((i = 0; i < 10; i++)); do
744                 rm -rf $DIR/$tdir/remote_dir_${i} ||
745                         error "destroy remote dir error $i"
746         done
747
748         check_fs_consistency_17n ||
749                 error "e2fsck report error after unlink files under remote dir"
750
751         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
752                 skip "lustre < 2.4.50 does not support migrate mv"
753
754         for ((i = 0; i < 10; i++)); do
755                 mkdir -p $DIR/$tdir/remote_dir_${i}
756                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
757                         error "create files under remote dir failed $i"
758                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
759                         error "migrate remote dir error $i"
760         done
761         check_fs_consistency_17n || error "e2fsck report error after migration"
762
763         for ((i = 0; i < 10; i++)); do
764                 rm -rf $DIR/$tdir/remote_dir_${i} ||
765                         error "destroy remote dir error $i"
766         done
767
768         check_fs_consistency_17n || error "e2fsck report error after unlink"
769 }
770 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
771
772 test_17o() {
773         remote_mds_nodsh && skip "remote MDS with nodsh"
774         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
775                 skip "Need MDS version at least 2.3.64"
776
777         local wdir=$DIR/${tdir}o
778         local mdt_index
779         local rc=0
780
781         test_mkdir $wdir
782         touch $wdir/$tfile
783         mdt_index=$($LFS getstripe -m $wdir/$tfile)
784         mdt_index=$((mdt_index + 1))
785
786         cancel_lru_locks mdc
787         #fail mds will wait the failover finish then set
788         #following fail_loc to avoid interfer the recovery process.
789         fail mds${mdt_index}
790
791         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
792         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
793         ls -l $wdir/$tfile && rc=1
794         do_facet mds${mdt_index} lctl set_param fail_loc=0
795         [[ $rc -eq 0 ]] || error "stat file should fail"
796 }
797 run_test 17o "stat file with incompat LMA feature"
798
799 test_18() {
800         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
801         ls $DIR || error "Failed to ls $DIR: $?"
802 }
803 run_test 18 "touch .../f ; ls ... =============================="
804
805 test_19a() {
806         touch $DIR/$tfile
807         ls -l $DIR
808         rm $DIR/$tfile
809         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
810 }
811 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
812
813 test_19b() {
814         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
815 }
816 run_test 19b "ls -l .../f19 (should return error) =============="
817
818 test_19c() {
819         [ $RUNAS_ID -eq $UID ] &&
820                 skip_env "RUNAS_ID = UID = $UID -- skipping"
821
822         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
823 }
824 run_test 19c "$RUNAS touch .../f19 (should return error) =="
825
826 test_19d() {
827         cat $DIR/f19 && error || true
828 }
829 run_test 19d "cat .../f19 (should return error) =============="
830
831 test_20() {
832         touch $DIR/$tfile
833         rm $DIR/$tfile
834         touch $DIR/$tfile
835         rm $DIR/$tfile
836         touch $DIR/$tfile
837         rm $DIR/$tfile
838         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
839 }
840 run_test 20 "touch .../f ; ls -l ..."
841
842 test_21() {
843         test_mkdir $DIR/$tdir
844         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
845         ln -s dangle $DIR/$tdir/link
846         echo foo >> $DIR/$tdir/link
847         cat $DIR/$tdir/dangle
848         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
849         $CHECKSTAT -f -t file $DIR/$tdir/link ||
850                 error "$tdir/link not linked to a file"
851 }
852 run_test 21 "write to dangling link"
853
854 test_22() {
855         local wdir=$DIR/$tdir
856         test_mkdir $wdir
857         chown $RUNAS_ID:$RUNAS_GID $wdir
858         (cd $wdir || error "cd $wdir failed";
859                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
860                 $RUNAS tar xf -)
861         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
862         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
863         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
864                 error "checkstat -u failed"
865 }
866 run_test 22 "unpack tar archive as non-root user"
867
868 # was test_23
869 test_23a() {
870         test_mkdir $DIR/$tdir
871         local file=$DIR/$tdir/$tfile
872
873         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
874         openfile -f O_CREAT:O_EXCL $file &&
875                 error "$file recreate succeeded" || true
876 }
877 run_test 23a "O_CREAT|O_EXCL in subdir"
878
879 test_23b() { # bug 18988
880         test_mkdir $DIR/$tdir
881         local file=$DIR/$tdir/$tfile
882
883         rm -f $file
884         echo foo > $file || error "write filed"
885         echo bar >> $file || error "append filed"
886         $CHECKSTAT -s 8 $file || error "wrong size"
887         rm $file
888 }
889 run_test 23b "O_APPEND check"
890
891 # LU-9409, size with O_APPEND and tiny writes
892 test_23c() {
893         local file=$DIR/$tfile
894
895         # single dd
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
897         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
898         rm -f $file
899
900         # racing tiny writes
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
902         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
903         wait
904         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
905         rm -f $file
906
907         #racing tiny & normal writes
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
909         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
910         wait
911         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
912         rm -f $file
913
914         #racing tiny & normal writes 2, ugly numbers
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
917         wait
918         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
919         rm -f $file
920 }
921 run_test 23c "O_APPEND size checks for tiny writes"
922
923 # LU-11069 file offset is correct after appending writes
924 test_23d() {
925         local file=$DIR/$tfile
926         local offset
927
928         echo CentaurHauls > $file
929         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
930         if ((offset != 26)); then
931                 error "wrong offset, expected 26, got '$offset'"
932         fi
933 }
934 run_test 23d "file offset is correct after appending writes"
935
936 # rename sanity
937 test_24a() {
938         echo '-- same directory rename'
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.1
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
943 }
944 run_test 24a "rename file to non-existent target"
945
946 test_24b() {
947         test_mkdir $DIR/$tdir
948         touch $DIR/$tdir/$tfile.{1,2}
949         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
950         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
951         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
952 }
953 run_test 24b "rename file to existing target"
954
955 test_24c() {
956         test_mkdir $DIR/$tdir
957         test_mkdir $DIR/$tdir/d$testnum.1
958         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
959         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
960         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
961 }
962 run_test 24c "rename directory to non-existent target"
963
964 test_24d() {
965         test_mkdir -c1 $DIR/$tdir
966         test_mkdir -c1 $DIR/$tdir/d$testnum.1
967         test_mkdir -c1 $DIR/$tdir/d$testnum.2
968         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
969         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
970         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
971 }
972 run_test 24d "rename directory to existing target"
973
974 test_24e() {
975         echo '-- cross directory renames --'
976         test_mkdir $DIR/R5a
977         test_mkdir $DIR/R5b
978         touch $DIR/R5a/f
979         mv $DIR/R5a/f $DIR/R5b/g
980         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
981         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
982 }
983 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
984
985 test_24f() {
986         test_mkdir $DIR/R6a
987         test_mkdir $DIR/R6b
988         touch $DIR/R6a/f $DIR/R6b/g
989         mv $DIR/R6a/f $DIR/R6b/g
990         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
991         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
992 }
993 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
994
995 test_24g() {
996         test_mkdir $DIR/R7a
997         test_mkdir $DIR/R7b
998         test_mkdir $DIR/R7a/d
999         mv $DIR/R7a/d $DIR/R7b/e
1000         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1001         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1002 }
1003 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1004
1005 test_24h() {
1006         test_mkdir -c1 $DIR/R8a
1007         test_mkdir -c1 $DIR/R8b
1008         test_mkdir -c1 $DIR/R8a/d
1009         test_mkdir -c1 $DIR/R8b/e
1010         mrename $DIR/R8a/d $DIR/R8b/e
1011         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1012         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1013 }
1014 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1015
1016 test_24i() {
1017         echo "-- rename error cases"
1018         test_mkdir $DIR/R9
1019         test_mkdir $DIR/R9/a
1020         touch $DIR/R9/f
1021         mrename $DIR/R9/f $DIR/R9/a
1022         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1023         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1024         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1025 }
1026 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1027
1028 test_24j() {
1029         test_mkdir $DIR/R10
1030         mrename $DIR/R10/f $DIR/R10/g
1031         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1032         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1033         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1034 }
1035 run_test 24j "source does not exist ============================"
1036
1037 test_24k() {
1038         test_mkdir $DIR/R11a
1039         test_mkdir $DIR/R11a/d
1040         touch $DIR/R11a/f
1041         mv $DIR/R11a/f $DIR/R11a/d
1042         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1043         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1044 }
1045 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1046
1047 # bug 2429 - rename foo foo foo creates invalid file
1048 test_24l() {
1049         f="$DIR/f24l"
1050         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1051 }
1052 run_test 24l "Renaming a file to itself ========================"
1053
1054 test_24m() {
1055         f="$DIR/f24m"
1056         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1057         # on ext3 this does not remove either the source or target files
1058         # though the "expected" operation would be to remove the source
1059         $CHECKSTAT -t file ${f} || error "${f} missing"
1060         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1061 }
1062 run_test 24m "Renaming a file to a hard link to itself ========="
1063
1064 test_24n() {
1065     f="$DIR/f24n"
1066     # this stats the old file after it was renamed, so it should fail
1067     touch ${f}
1068     $CHECKSTAT ${f} || error "${f} missing"
1069     mv ${f} ${f}.rename
1070     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1071     $CHECKSTAT -a ${f} || error "${f} exists"
1072 }
1073 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1074
1075 test_24o() {
1076         test_mkdir $DIR/$tdir
1077         rename_many -s random -v -n 10 $DIR/$tdir
1078 }
1079 run_test 24o "rename of files during htree split"
1080
1081 test_24p() {
1082         test_mkdir $DIR/R12a
1083         test_mkdir $DIR/R12b
1084         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1085         mrename $DIR/R12a $DIR/R12b
1086         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1087         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1088         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1089         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1090 }
1091 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1092
1093 cleanup_multiop_pause() {
1094         trap 0
1095         kill -USR1 $MULTIPID
1096 }
1097
1098 test_24q() {
1099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1100
1101         test_mkdir $DIR/R13a
1102         test_mkdir $DIR/R13b
1103         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1104         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1105         MULTIPID=$!
1106
1107         trap cleanup_multiop_pause EXIT
1108         mrename $DIR/R13a $DIR/R13b
1109         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1110         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1111         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1112         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1113         cleanup_multiop_pause
1114         wait $MULTIPID || error "multiop close failed"
1115 }
1116 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1117
1118 test_24r() { #bug 3789
1119         test_mkdir $DIR/R14a
1120         test_mkdir $DIR/R14a/b
1121         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1122         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1123         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1124 }
1125 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1126
1127 test_24s() {
1128         test_mkdir $DIR/R15a
1129         test_mkdir $DIR/R15a/b
1130         test_mkdir $DIR/R15a/b/c
1131         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1132         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1133         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1134 }
1135 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1136 test_24t() {
1137         test_mkdir $DIR/R16a
1138         test_mkdir $DIR/R16a/b
1139         test_mkdir $DIR/R16a/b/c
1140         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1141         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1142         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1143 }
1144 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1145
1146 test_24u() { # bug12192
1147         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1148         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1149 }
1150 run_test 24u "create stripe file"
1151
1152 simple_cleanup_common() {
1153         local rc=0
1154         trap 0
1155         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1156
1157         local start=$SECONDS
1158         rm -rf $DIR/$tdir
1159         rc=$?
1160         wait_delete_completed
1161         echo "cleanup time $((SECONDS - start))"
1162         return $rc
1163 }
1164
1165 max_pages_per_rpc() {
1166         local mdtname="$(printf "MDT%04x" ${1:-0})"
1167         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1168 }
1169
1170 test_24v() {
1171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1172
1173         local nrfiles=${COUNT:-100000}
1174         local fname="$DIR/$tdir/$tfile"
1175
1176         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1177         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1178
1179         test_mkdir "$(dirname $fname)"
1180         # assume MDT0000 has the fewest inodes
1181         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1182         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1183         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1184
1185         trap simple_cleanup_common EXIT
1186
1187         createmany -m "$fname" $nrfiles
1188
1189         cancel_lru_locks mdc
1190         lctl set_param mdc.*.stats clear
1191
1192         # was previously test_24D: LU-6101
1193         # readdir() returns correct number of entries after cursor reload
1194         local num_ls=$(ls $DIR/$tdir | wc -l)
1195         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1196         local num_all=$(ls -a $DIR/$tdir | wc -l)
1197         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1198                 [ $num_all -ne $((nrfiles + 2)) ]; then
1199                         error "Expected $nrfiles files, got $num_ls " \
1200                                 "($num_uniq unique $num_all .&..)"
1201         fi
1202         # LU-5 large readdir
1203         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1204         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1205         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1206         # take into account of overhead in lu_dirpage header and end mark in
1207         # each page, plus one in rpc_num calculation.
1208         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1209         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1210         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1211         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1212         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1213         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1214         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1215         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1216                 error "large readdir doesn't take effect: " \
1217                       "$mds_readpage should be about $rpc_max"
1218
1219         simple_cleanup_common
1220 }
1221 run_test 24v "list large directory (test hash collision, b=17560)"
1222
1223 test_24w() { # bug21506
1224         SZ1=234852
1225         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1226         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1227         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1228         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1229         [[ "$SZ1" -eq "$SZ2" ]] ||
1230                 error "Error reading at the end of the file $tfile"
1231 }
1232 run_test 24w "Reading a file larger than 4Gb"
1233
1234 test_24x() {
1235         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1237         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1238                 skip "Need MDS version at least 2.7.56"
1239
1240         local MDTIDX=1
1241         local remote_dir=$DIR/$tdir/remote_dir
1242
1243         test_mkdir $DIR/$tdir
1244         $LFS mkdir -i $MDTIDX $remote_dir ||
1245                 error "create remote directory failed"
1246
1247         test_mkdir $DIR/$tdir/src_dir
1248         touch $DIR/$tdir/src_file
1249         test_mkdir $remote_dir/tgt_dir
1250         touch $remote_dir/tgt_file
1251
1252         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1253                 error "rename dir cross MDT failed!"
1254
1255         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1256                 error "rename file cross MDT failed!"
1257
1258         touch $DIR/$tdir/ln_file
1259         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1260                 error "ln file cross MDT failed"
1261
1262         rm -rf $DIR/$tdir || error "Can not delete directories"
1263 }
1264 run_test 24x "cross MDT rename/link"
1265
1266 test_24y() {
1267         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1269
1270         local remote_dir=$DIR/$tdir/remote_dir
1271         local mdtidx=1
1272
1273         test_mkdir $DIR/$tdir
1274         $LFS mkdir -i $mdtidx $remote_dir ||
1275                 error "create remote directory failed"
1276
1277         test_mkdir $remote_dir/src_dir
1278         touch $remote_dir/src_file
1279         test_mkdir $remote_dir/tgt_dir
1280         touch $remote_dir/tgt_file
1281
1282         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1283                 error "rename subdir in the same remote dir failed!"
1284
1285         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1286                 error "rename files in the same remote dir failed!"
1287
1288         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1289                 error "link files in the same remote dir failed!"
1290
1291         rm -rf $DIR/$tdir || error "Can not delete directories"
1292 }
1293 run_test 24y "rename/link on the same dir should succeed"
1294
1295 test_24z() {
1296         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1297         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1298                 skip "Need MDS version at least 2.12.51"
1299
1300         local index
1301
1302         for index in 0 1; do
1303                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1304                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1305         done
1306
1307         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1308
1309         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1310         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1311
1312         local mdts=$(comma_list $(mdts_nodes))
1313
1314         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1315         stack_trap "do_nodes $mdts $LCTL \
1316                 set_param mdt.*.enable_remote_rename=1" EXIT
1317
1318         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1319
1320         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1321         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1322 }
1323 run_test 24z "cross-MDT rename is done as cp"
1324
1325 test_24A() { # LU-3182
1326         local NFILES=5000
1327
1328         rm -rf $DIR/$tdir
1329         test_mkdir $DIR/$tdir
1330         trap simple_cleanup_common EXIT
1331         createmany -m $DIR/$tdir/$tfile $NFILES
1332         local t=$(ls $DIR/$tdir | wc -l)
1333         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1334         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1335         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1336            [ $v -ne $((NFILES + 2)) ] ; then
1337                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1338         fi
1339
1340         simple_cleanup_common || error "Can not delete directories"
1341 }
1342 run_test 24A "readdir() returns correct number of entries."
1343
1344 test_24B() { # LU-4805
1345         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1346
1347         local count
1348
1349         test_mkdir $DIR/$tdir
1350         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1351                 error "create striped dir failed"
1352
1353         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1354         [ $count -eq 2 ] || error "Expected 2, got $count"
1355
1356         touch $DIR/$tdir/striped_dir/a
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 3 ] || error "Expected 3, got $count"
1360
1361         touch $DIR/$tdir/striped_dir/.f
1362
1363         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1364         [ $count -eq 4 ] || error "Expected 4, got $count"
1365
1366         rm -rf $DIR/$tdir || error "Can not delete directories"
1367 }
1368 run_test 24B "readdir for striped dir return correct number of entries"
1369
1370 test_24C() {
1371         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1372
1373         mkdir $DIR/$tdir
1374         mkdir $DIR/$tdir/d0
1375         mkdir $DIR/$tdir/d1
1376
1377         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1378                 error "create striped dir failed"
1379
1380         cd $DIR/$tdir/d0/striped_dir
1381
1382         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1383         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1384         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d0_ino" = "$parent_ino" ] ||
1387                 error ".. wrong, expect $d0_ino, get $parent_ino"
1388
1389         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1390                 error "mv striped dir failed"
1391
1392         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1393
1394         [ "$d1_ino" = "$parent_ino" ] ||
1395                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1396 }
1397 run_test 24C "check .. in striped dir"
1398
1399 test_24E() {
1400         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1402
1403         mkdir -p $DIR/$tdir
1404         mkdir $DIR/$tdir/src_dir
1405         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1406                 error "create remote source failed"
1407
1408         touch $DIR/$tdir/src_dir/src_child/a
1409
1410         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1411                 error "create remote target dir failed"
1412
1413         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1414                 error "create remote target child failed"
1415
1416         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "rename dir cross MDT failed!"
1418
1419         find $DIR/$tdir
1420
1421         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1422                 error "src_child still exists after rename"
1423
1424         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1425                 error "missing file(a) after rename"
1426
1427         rm -rf $DIR/$tdir || error "Can not delete directories"
1428 }
1429 run_test 24E "cross MDT rename/link"
1430
1431 test_24F () {
1432         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1433
1434         local repeats=1000
1435         [ "$SLOW" = "no" ] && repeats=100
1436
1437         mkdir -p $DIR/$tdir
1438
1439         echo "$repeats repeats"
1440         for ((i = 0; i < repeats; i++)); do
1441                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1442                 touch $DIR/$tdir/test/a || error "touch fails"
1443                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1444                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1445         done
1446
1447         true
1448 }
1449 run_test 24F "hash order vs readdir (LU-11330)"
1450
1451 test_25a() {
1452         echo '== symlink sanity ============================================='
1453
1454         test_mkdir $DIR/d25
1455         ln -s d25 $DIR/s25
1456         touch $DIR/s25/foo ||
1457                 error "File creation in symlinked directory failed"
1458 }
1459 run_test 25a "create file in symlinked directory ==============="
1460
1461 test_25b() {
1462         [ ! -d $DIR/d25 ] && test_25a
1463         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1464 }
1465 run_test 25b "lookup file in symlinked directory ==============="
1466
1467 test_26a() {
1468         test_mkdir $DIR/d26
1469         test_mkdir $DIR/d26/d26-2
1470         ln -s d26/d26-2 $DIR/s26
1471         touch $DIR/s26/foo || error "File creation failed"
1472 }
1473 run_test 26a "multiple component symlink ======================="
1474
1475 test_26b() {
1476         test_mkdir -p $DIR/$tdir/d26-2
1477         ln -s $tdir/d26-2/foo $DIR/s26-2
1478         touch $DIR/s26-2 || error "File creation failed"
1479 }
1480 run_test 26b "multiple component symlink at end of lookup ======"
1481
1482 test_26c() {
1483         test_mkdir $DIR/d26.2
1484         touch $DIR/d26.2/foo
1485         ln -s d26.2 $DIR/s26.2-1
1486         ln -s s26.2-1 $DIR/s26.2-2
1487         ln -s s26.2-2 $DIR/s26.2-3
1488         chmod 0666 $DIR/s26.2-3/foo
1489 }
1490 run_test 26c "chain of symlinks"
1491
1492 # recursive symlinks (bug 439)
1493 test_26d() {
1494         ln -s d26-3/foo $DIR/d26-3
1495 }
1496 run_test 26d "create multiple component recursive symlink"
1497
1498 test_26e() {
1499         [ ! -h $DIR/d26-3 ] && test_26d
1500         rm $DIR/d26-3
1501 }
1502 run_test 26e "unlink multiple component recursive symlink"
1503
1504 # recursive symlinks (bug 7022)
1505 test_26f() {
1506         test_mkdir $DIR/$tdir
1507         test_mkdir $DIR/$tdir/$tfile
1508         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1509         test_mkdir -p lndir/bar1
1510         test_mkdir $DIR/$tdir/$tfile/$tfile
1511         cd $tfile                || error "cd $tfile failed"
1512         ln -s .. dotdot          || error "ln dotdot failed"
1513         ln -s dotdot/lndir lndir || error "ln lndir failed"
1514         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1515         output=`ls $tfile/$tfile/lndir/bar1`
1516         [ "$output" = bar1 ] && error "unexpected output"
1517         rm -r $tfile             || error "rm $tfile failed"
1518         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1519 }
1520 run_test 26f "rm -r of a directory which has recursive symlink"
1521
1522 test_27a() {
1523         test_mkdir $DIR/$tdir
1524         $LFS getstripe $DIR/$tdir
1525         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1526         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1527         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1528 }
1529 run_test 27a "one stripe file"
1530
1531 test_27b() {
1532         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1533
1534         test_mkdir $DIR/$tdir
1535         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1536         $LFS getstripe -c $DIR/$tdir/$tfile
1537         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1538                 error "two-stripe file doesn't have two stripes"
1539
1540         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1541 }
1542 run_test 27b "create and write to two stripe file"
1543
1544 # 27c family tests specific striping, setstripe -o
1545 test_27ca() {
1546         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1547         test_mkdir -p $DIR/$tdir
1548         local osts="1"
1549
1550         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1551         $LFS getstripe -i $DIR/$tdir/$tfile
1552         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1553                 error "stripe not on specified OST"
1554
1555         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1556 }
1557 run_test 27ca "one stripe on specified OST"
1558
1559 test_27cb() {
1560         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1561         test_mkdir -p $DIR/$tdir
1562         local osts="1,0"
1563         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1564         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1565         echo "$getstripe"
1566
1567         # Strip getstripe output to a space separated list of OSTs
1568         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1569                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1570         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1571                 error "stripes not on specified OSTs"
1572
1573         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1574 }
1575 run_test 27cb "two stripes on specified OSTs"
1576
1577 test_27cc() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1579         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1580                 skip "server does not support overstriping"
1581
1582         test_mkdir -p $DIR/$tdir
1583         local osts="0,0"
1584         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1585         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1586         echo "$getstripe"
1587
1588         # Strip getstripe output to a space separated list of OSTs
1589         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1590                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1591         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1592                 error "stripes not on specified OSTs"
1593
1594         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1595 }
1596 run_test 27cc "two stripes on the same OST"
1597
1598 test_27cd() {
1599         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1600         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1601                 skip "server does not support overstriping"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,1,1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cd "four stripes on two OSTs"
1617
1618 test_27ce() {
1619         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1620                 skip_env "too many osts, skipping"
1621         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1622                 skip "server does not support overstriping"
1623         # We do one more stripe than we have OSTs
1624         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1625                 skip_env "ea_inode feature disabled"
1626
1627         test_mkdir -p $DIR/$tdir
1628         local osts=""
1629         for i in $(seq 0 $OSTCOUNT);
1630         do
1631                 osts=$osts"0"
1632                 if [ $i -ne $OSTCOUNT ]; then
1633                         osts=$osts","
1634                 fi
1635         done
1636         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1637         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1638         echo "$getstripe"
1639
1640         # Strip getstripe output to a space separated list of OSTs
1641         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1642                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1643         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1644                 error "stripes not on specified OSTs"
1645
1646         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1647 }
1648 run_test 27ce "more stripes than OSTs with -o"
1649
1650 test_27cf() {
1651         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1652         local pid=0
1653
1654         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1655         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1656         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1657         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1658                 error "failed to set $osp_proc=0"
1659
1660         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1661         pid=$!
1662         sleep 1
1663         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1664         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1665                 error "failed to set $osp_proc=1"
1666         wait $pid
1667         [[ $pid -ne 0 ]] ||
1668                 error "should return error due to $osp_proc=0"
1669 }
1670 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1671
1672 test_27d() {
1673         test_mkdir $DIR/$tdir
1674         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1675                 error "setstripe failed"
1676         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1677         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1678 }
1679 run_test 27d "create file with default settings"
1680
1681 test_27e() {
1682         # LU-5839 adds check for existed layout before setting it
1683         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1684                 skip "Need MDS version at least 2.7.56"
1685
1686         test_mkdir $DIR/$tdir
1687         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1688         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1689         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1690 }
1691 run_test 27e "setstripe existing file (should return error)"
1692
1693 test_27f() {
1694         test_mkdir $DIR/$tdir
1695         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1696                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1697         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1698                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1699         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1700         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1701 }
1702 run_test 27f "setstripe with bad stripe size (should return error)"
1703
1704 test_27g() {
1705         test_mkdir $DIR/$tdir
1706         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1707         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1708                 error "$DIR/$tdir/$tfile has object"
1709 }
1710 run_test 27g "$LFS getstripe with no objects"
1711
1712 test_27ga() {
1713         test_mkdir $DIR/$tdir
1714         touch $DIR/$tdir/$tfile || error "touch failed"
1715         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1716         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1717         local rc=$?
1718         (( rc == 2 )) || error "getstripe did not return ENOENT"
1719 }
1720 run_test 27ga "$LFS getstripe with missing file (should return error)"
1721
1722 test_27i() {
1723         test_mkdir $DIR/$tdir
1724         touch $DIR/$tdir/$tfile || error "touch failed"
1725         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1726                 error "missing objects"
1727 }
1728 run_test 27i "$LFS getstripe with some objects"
1729
1730 test_27j() {
1731         test_mkdir $DIR/$tdir
1732         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1733                 error "setstripe failed" || true
1734 }
1735 run_test 27j "setstripe with bad stripe offset (should return error)"
1736
1737 test_27k() { # bug 2844
1738         test_mkdir $DIR/$tdir
1739         local file=$DIR/$tdir/$tfile
1740         local ll_max_blksize=$((4 * 1024 * 1024))
1741         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1742         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1743         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1744         dd if=/dev/zero of=$file bs=4k count=1
1745         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1746         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1747 }
1748 run_test 27k "limit i_blksize for broken user apps"
1749
1750 test_27l() {
1751         mcreate $DIR/$tfile || error "creating file"
1752         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1753                 error "setstripe should have failed" || true
1754 }
1755 run_test 27l "check setstripe permissions (should return error)"
1756
1757 test_27m() {
1758         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1759
1760         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1761                 skip_env "multiple clients -- skipping"
1762
1763         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1764                    head -n1)
1765         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1766                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1767         fi
1768         trap simple_cleanup_common EXIT
1769         test_mkdir $DIR/$tdir
1770         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1771         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1772                 error "dd should fill OST0"
1773         i=2
1774         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1775                 i=$((i + 1))
1776                 [ $i -gt 256 ] && break
1777         done
1778         i=$((i + 1))
1779         touch $DIR/$tdir/$tfile.$i
1780         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1781             awk '{print $1}'| grep -w "0") ] &&
1782                 error "OST0 was full but new created file still use it"
1783         i=$((i + 1))
1784         touch $DIR/$tdir/$tfile.$i
1785         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1786             awk '{print $1}'| grep -w "0") ] &&
1787                 error "OST0 was full but new created file still use it"
1788         simple_cleanup_common
1789 }
1790 run_test 27m "create file while OST0 was full"
1791
1792 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1793 # if the OST isn't full anymore.
1794 reset_enospc() {
1795         local ostidx=${1:-""}
1796         local delay
1797         local ready
1798         local get_prealloc
1799
1800         local list=$(comma_list $(osts_nodes))
1801         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1802
1803         do_nodes $list lctl set_param fail_loc=0
1804         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1805         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1806                 awk '{print $1 * 2;exit;}')
1807         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1808                         grep -v \"^0$\""
1809         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1810 }
1811
1812 __exhaust_precreations() {
1813         local OSTIDX=$1
1814         local FAILLOC=$2
1815         local FAILIDX=${3:-$OSTIDX}
1816         local ofacet=ost$((OSTIDX + 1))
1817
1818         test_mkdir -p -c1 $DIR/$tdir
1819         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1820         local mfacet=mds$((mdtidx + 1))
1821         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1822
1823         local OST=$(ostname_from_index $OSTIDX)
1824
1825         # on the mdt's osc
1826         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1827         local last_id=$(do_facet $mfacet lctl get_param -n \
1828                         osp.$mdtosc_proc1.prealloc_last_id)
1829         local next_id=$(do_facet $mfacet lctl get_param -n \
1830                         osp.$mdtosc_proc1.prealloc_next_id)
1831
1832         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1833         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1834
1835         test_mkdir -p $DIR/$tdir/${OST}
1836         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1837 #define OBD_FAIL_OST_ENOSPC              0x215
1838         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1839         echo "Creating to objid $last_id on ost $OST..."
1840         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1841         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1842         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1843 }
1844
1845 exhaust_precreations() {
1846         __exhaust_precreations $1 $2 $3
1847         sleep_maxage
1848 }
1849
1850 exhaust_all_precreations() {
1851         local i
1852         for (( i=0; i < OSTCOUNT; i++ )) ; do
1853                 __exhaust_precreations $i $1 -1
1854         done
1855         sleep_maxage
1856 }
1857
1858 test_27n() {
1859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1861         remote_mds_nodsh && skip "remote MDS with nodsh"
1862         remote_ost_nodsh && skip "remote OST with nodsh"
1863
1864         reset_enospc
1865         rm -f $DIR/$tdir/$tfile
1866         exhaust_precreations 0 0x80000215
1867         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1868         touch $DIR/$tdir/$tfile || error "touch failed"
1869         $LFS getstripe $DIR/$tdir/$tfile
1870         reset_enospc
1871 }
1872 run_test 27n "create file with some full OSTs"
1873
1874 test_27o() {
1875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1877         remote_mds_nodsh && skip "remote MDS with nodsh"
1878         remote_ost_nodsh && skip "remote OST with nodsh"
1879
1880         reset_enospc
1881         rm -f $DIR/$tdir/$tfile
1882         exhaust_all_precreations 0x215
1883
1884         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1885
1886         reset_enospc
1887         rm -rf $DIR/$tdir/*
1888 }
1889 run_test 27o "create file with all full OSTs (should error)"
1890
1891 test_27p() {
1892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1894         remote_mds_nodsh && skip "remote MDS with nodsh"
1895         remote_ost_nodsh && skip "remote OST with nodsh"
1896
1897         reset_enospc
1898         rm -f $DIR/$tdir/$tfile
1899         test_mkdir $DIR/$tdir
1900
1901         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1902         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1903         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1904
1905         exhaust_precreations 0 0x80000215
1906         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1907         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1908         $LFS getstripe $DIR/$tdir/$tfile
1909
1910         reset_enospc
1911 }
1912 run_test 27p "append to a truncated file with some full OSTs"
1913
1914 test_27q() {
1915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1917         remote_mds_nodsh && skip "remote MDS with nodsh"
1918         remote_ost_nodsh && skip "remote OST with nodsh"
1919
1920         reset_enospc
1921         rm -f $DIR/$tdir/$tfile
1922
1923         test_mkdir $DIR/$tdir
1924         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1925         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1926                 error "truncate $DIR/$tdir/$tfile failed"
1927         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1928
1929         exhaust_all_precreations 0x215
1930
1931         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1932         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1933
1934         reset_enospc
1935 }
1936 run_test 27q "append to truncated file with all OSTs full (should error)"
1937
1938 test_27r() {
1939         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1941         remote_mds_nodsh && skip "remote MDS with nodsh"
1942         remote_ost_nodsh && skip "remote OST with nodsh"
1943
1944         reset_enospc
1945         rm -f $DIR/$tdir/$tfile
1946         exhaust_precreations 0 0x80000215
1947
1948         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1949
1950         reset_enospc
1951 }
1952 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1953
1954 test_27s() { # bug 10725
1955         test_mkdir $DIR/$tdir
1956         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1957         local stripe_count=0
1958         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1959         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1960                 error "stripe width >= 2^32 succeeded" || true
1961
1962 }
1963 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1964
1965 test_27t() { # bug 10864
1966         WDIR=$(pwd)
1967         WLFS=$(which lfs)
1968         cd $DIR
1969         touch $tfile
1970         $WLFS getstripe $tfile
1971         cd $WDIR
1972 }
1973 run_test 27t "check that utils parse path correctly"
1974
1975 test_27u() { # bug 4900
1976         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1977         remote_mds_nodsh && skip "remote MDS with nodsh"
1978
1979         local index
1980         local list=$(comma_list $(mdts_nodes))
1981
1982 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1983         do_nodes $list $LCTL set_param fail_loc=0x139
1984         test_mkdir -p $DIR/$tdir
1985         trap simple_cleanup_common EXIT
1986         createmany -o $DIR/$tdir/t- 1000
1987         do_nodes $list $LCTL set_param fail_loc=0
1988
1989         TLOG=$TMP/$tfile.getstripe
1990         $LFS getstripe $DIR/$tdir > $TLOG
1991         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1992         unlinkmany $DIR/$tdir/t- 1000
1993         trap 0
1994         [[ $OBJS -gt 0 ]] &&
1995                 error "$OBJS objects created on OST-0. See $TLOG" ||
1996                 rm -f $TLOG
1997 }
1998 run_test 27u "skip object creation on OSC w/o objects"
1999
2000 test_27v() { # bug 4900
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003         remote_mds_nodsh && skip "remote MDS with nodsh"
2004         remote_ost_nodsh && skip "remote OST with nodsh"
2005
2006         exhaust_all_precreations 0x215
2007         reset_enospc
2008
2009         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2010
2011         touch $DIR/$tdir/$tfile
2012         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2013         # all except ost1
2014         for (( i=1; i < OSTCOUNT; i++ )); do
2015                 do_facet ost$i lctl set_param fail_loc=0x705
2016         done
2017         local START=`date +%s`
2018         createmany -o $DIR/$tdir/$tfile 32
2019
2020         local FINISH=`date +%s`
2021         local TIMEOUT=`lctl get_param -n timeout`
2022         local PROCESS=$((FINISH - START))
2023         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2024                error "$FINISH - $START >= $TIMEOUT / 2"
2025         sleep $((TIMEOUT / 2 - PROCESS))
2026         reset_enospc
2027 }
2028 run_test 27v "skip object creation on slow OST"
2029
2030 test_27w() { # bug 10997
2031         test_mkdir $DIR/$tdir
2032         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2033         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2034                 error "stripe size $size != 65536" || true
2035         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2036                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2037 }
2038 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2039
2040 test_27wa() {
2041         [[ $OSTCOUNT -lt 2 ]] &&
2042                 skip_env "skipping multiple stripe count/offset test"
2043
2044         test_mkdir $DIR/$tdir
2045         for i in $(seq 1 $OSTCOUNT); do
2046                 offset=$((i - 1))
2047                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2048                         error "setstripe -c $i -i $offset failed"
2049                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2050                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2051                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2052                 [ $index -ne $offset ] &&
2053                         error "stripe offset $index != $offset" || true
2054         done
2055 }
2056 run_test 27wa "check $LFS setstripe -c -i options"
2057
2058 test_27x() {
2059         remote_ost_nodsh && skip "remote OST with nodsh"
2060         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2062
2063         OFFSET=$(($OSTCOUNT - 1))
2064         OSTIDX=0
2065         local OST=$(ostname_from_index $OSTIDX)
2066
2067         test_mkdir $DIR/$tdir
2068         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2069         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2070         sleep_maxage
2071         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2072         for i in $(seq 0 $OFFSET); do
2073                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2074                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2075                 error "OST0 was degraded but new created file still use it"
2076         done
2077         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2078 }
2079 run_test 27x "create files while OST0 is degraded"
2080
2081 test_27y() {
2082         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2083         remote_mds_nodsh && skip "remote MDS with nodsh"
2084         remote_ost_nodsh && skip "remote OST with nodsh"
2085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2086
2087         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2088         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2089                 osp.$mdtosc.prealloc_last_id)
2090         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2091                 osp.$mdtosc.prealloc_next_id)
2092         local fcount=$((last_id - next_id))
2093         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2094         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2095
2096         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2097                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2098         local OST_DEACTIVE_IDX=-1
2099         local OSC
2100         local OSTIDX
2101         local OST
2102
2103         for OSC in $MDS_OSCS; do
2104                 OST=$(osc_to_ost $OSC)
2105                 OSTIDX=$(index_from_ostuuid $OST)
2106                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2107                         OST_DEACTIVE_IDX=$OSTIDX
2108                 fi
2109                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2110                         echo $OSC "is Deactivated:"
2111                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2112                 fi
2113         done
2114
2115         OSTIDX=$(index_from_ostuuid $OST)
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2118
2119         for OSC in $MDS_OSCS; do
2120                 OST=$(osc_to_ost $OSC)
2121                 OSTIDX=$(index_from_ostuuid $OST)
2122                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2123                         echo $OST "is degraded:"
2124                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2125                                                 obdfilter.$OST.degraded=1
2126                 fi
2127         done
2128
2129         sleep_maxage
2130         createmany -o $DIR/$tdir/$tfile $fcount
2131
2132         for OSC in $MDS_OSCS; do
2133                 OST=$(osc_to_ost $OSC)
2134                 OSTIDX=$(index_from_ostuuid $OST)
2135                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2136                         echo $OST "is recovered from degraded:"
2137                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2138                                                 obdfilter.$OST.degraded=0
2139                 else
2140                         do_facet $SINGLEMDS lctl --device %$OSC activate
2141                 fi
2142         done
2143
2144         # all osp devices get activated, hence -1 stripe count restored
2145         local stripe_count=0
2146
2147         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2148         # devices get activated.
2149         sleep_maxage
2150         $LFS setstripe -c -1 $DIR/$tfile
2151         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2152         rm -f $DIR/$tfile
2153         [ $stripe_count -ne $OSTCOUNT ] &&
2154                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2155         return 0
2156 }
2157 run_test 27y "create files while OST0 is degraded and the rest inactive"
2158
2159 check_seq_oid()
2160 {
2161         log "check file $1"
2162
2163         lmm_count=$($LFS getstripe -c $1)
2164         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2165         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2166
2167         local old_ifs="$IFS"
2168         IFS=$'[:]'
2169         fid=($($LFS path2fid $1))
2170         IFS="$old_ifs"
2171
2172         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2173         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2174
2175         # compare lmm_seq and lu_fid->f_seq
2176         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2177         # compare lmm_object_id and lu_fid->oid
2178         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2179
2180         # check the trusted.fid attribute of the OST objects of the file
2181         local have_obdidx=false
2182         local stripe_nr=0
2183         $LFS getstripe $1 | while read obdidx oid hex seq; do
2184                 # skip lines up to and including "obdidx"
2185                 [ -z "$obdidx" ] && break
2186                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2187                 $have_obdidx || continue
2188
2189                 local ost=$((obdidx + 1))
2190                 local dev=$(ostdevname $ost)
2191                 local oid_hex
2192
2193                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2194
2195                 seq=$(echo $seq | sed -e "s/^0x//g")
2196                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2197                         oid_hex=$(echo $oid)
2198                 else
2199                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2200                 fi
2201                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2202
2203                 local ff=""
2204                 #
2205                 # Don't unmount/remount the OSTs if we don't need to do that.
2206                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2207                 # update too, until that use mount/ll_decode_filter_fid/mount.
2208                 # Re-enable when debugfs will understand new filter_fid.
2209                 #
2210                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2211                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2212                                 $dev 2>/dev/null" | grep "parent=")
2213                 fi
2214                 if [ -z "$ff" ]; then
2215                         stop ost$ost
2216                         mount_fstype ost$ost
2217                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2218                                 $(facet_mntpt ost$ost)/$obj_file)
2219                         unmount_fstype ost$ost
2220                         start ost$ost $dev $OST_MOUNT_OPTS
2221                         clients_up
2222                 fi
2223
2224                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2225
2226                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2227
2228                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2229                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2230                 #
2231                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2232                 #       stripe_size=1048576 component_id=1 component_start=0 \
2233                 #       component_end=33554432
2234                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2235                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2236                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2237                 local ff_pstripe
2238                 if grep -q 'stripe=' <<<$ff; then
2239                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2240                 else
2241                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2242                         # into f_ver in this case.  See comment on ff_parent.
2243                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2244                 fi
2245
2246                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2247                 [ $ff_pseq = $lmm_seq ] ||
2248                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2249                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2250                 [ $ff_poid = $lmm_oid ] ||
2251                         error "FF parent OID $ff_poid != $lmm_oid"
2252                 (($ff_pstripe == $stripe_nr)) ||
2253                         error "FF stripe $ff_pstripe != $stripe_nr"
2254
2255                 stripe_nr=$((stripe_nr + 1))
2256                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2257                         continue
2258                 if grep -q 'stripe_count=' <<<$ff; then
2259                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2260                                             -e 's/ .*//' <<<$ff)
2261                         [ $lmm_count = $ff_scnt ] ||
2262                                 error "FF stripe count $lmm_count != $ff_scnt"
2263                 fi
2264         done
2265 }
2266
2267 test_27z() {
2268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2269         remote_ost_nodsh && skip "remote OST with nodsh"
2270
2271         test_mkdir $DIR/$tdir
2272         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2273                 { error "setstripe -c -1 failed"; return 1; }
2274         # We need to send a write to every object to get parent FID info set.
2275         # This _should_ also work for setattr, but does not currently.
2276         # touch $DIR/$tdir/$tfile-1 ||
2277         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2278                 { error "dd $tfile-1 failed"; return 2; }
2279         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2280                 { error "setstripe -c -1 failed"; return 3; }
2281         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2282                 { error "dd $tfile-2 failed"; return 4; }
2283
2284         # make sure write RPCs have been sent to OSTs
2285         sync; sleep 5; sync
2286
2287         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2288         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2289 }
2290 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2291
2292 test_27A() { # b=19102
2293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2294
2295         save_layout_restore_at_exit $MOUNT
2296         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2297         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2298                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2299         local default_size=$($LFS getstripe -S $MOUNT)
2300         local default_offset=$($LFS getstripe -i $MOUNT)
2301         local dsize=$(do_facet $SINGLEMDS \
2302                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2303         [ $default_size -eq $dsize ] ||
2304                 error "stripe size $default_size != $dsize"
2305         [ $default_offset -eq -1 ] ||
2306                 error "stripe offset $default_offset != -1"
2307 }
2308 run_test 27A "check filesystem-wide default LOV EA values"
2309
2310 test_27B() { # LU-2523
2311         test_mkdir $DIR/$tdir
2312         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2313         touch $DIR/$tdir/f0
2314         # open f1 with O_LOV_DELAY_CREATE
2315         # rename f0 onto f1
2316         # call setstripe ioctl on open file descriptor for f1
2317         # close
2318         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2319                 $DIR/$tdir/f0
2320
2321         rm -f $DIR/$tdir/f1
2322         # open f1 with O_LOV_DELAY_CREATE
2323         # unlink f1
2324         # call setstripe ioctl on open file descriptor for f1
2325         # close
2326         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2327
2328         # Allow multiop to fail in imitation of NFS's busted semantics.
2329         true
2330 }
2331 run_test 27B "call setstripe on open unlinked file/rename victim"
2332
2333 # 27C family tests full striping and overstriping
2334 test_27Ca() { #LU-2871
2335         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2336
2337         declare -a ost_idx
2338         local index
2339         local found
2340         local i
2341         local j
2342
2343         test_mkdir $DIR/$tdir
2344         cd $DIR/$tdir
2345         for i in $(seq 0 $((OSTCOUNT - 1))); do
2346                 # set stripe across all OSTs starting from OST$i
2347                 $LFS setstripe -i $i -c -1 $tfile$i
2348                 # get striping information
2349                 ost_idx=($($LFS getstripe $tfile$i |
2350                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2351                 echo ${ost_idx[@]}
2352
2353                 # check the layout
2354                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2355                         error "${#ost_idx[@]} != $OSTCOUNT"
2356
2357                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2358                         found=0
2359                         for j in $(echo ${ost_idx[@]}); do
2360                                 if [ $index -eq $j ]; then
2361                                         found=1
2362                                         break
2363                                 fi
2364                         done
2365                         [ $found = 1 ] ||
2366                                 error "Can not find $index in ${ost_idx[@]}"
2367                 done
2368         done
2369 }
2370 run_test 27Ca "check full striping across all OSTs"
2371
2372 test_27Cb() {
2373         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2374                 skip "server does not support overstriping"
2375         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2376                 skip_env "too many osts, skipping"
2377
2378         test_mkdir -p $DIR/$tdir
2379         local setcount=$(($OSTCOUNT * 2))
2380         [ $setcount -ge 160 ] || large_xattr_enabled ||
2381                 skip_env "ea_inode feature disabled"
2382
2383         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2384                 error "setstripe failed"
2385
2386         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2387         [ $count -eq $setcount ] ||
2388                 error "stripe count $count, should be $setcount"
2389
2390         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2391                 error "overstriped should be set in pattern"
2392
2393         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2394                 error "dd failed"
2395 }
2396 run_test 27Cb "more stripes than OSTs with -C"
2397
2398 test_27Cc() {
2399         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2400                 skip "server does not support overstriping"
2401         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2402
2403         test_mkdir -p $DIR/$tdir
2404         local setcount=$(($OSTCOUNT - 1))
2405
2406         [ $setcount -ge 160 ] || large_xattr_enabled ||
2407                 skip_env "ea_inode feature disabled"
2408
2409         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2410                 error "setstripe failed"
2411
2412         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2413         [ $count -eq $setcount ] ||
2414                 error "stripe count $count, should be $setcount"
2415
2416         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2417                 error "overstriped should not be set in pattern"
2418
2419         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2420                 error "dd failed"
2421 }
2422 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2423
2424 test_27Cd() {
2425         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2426                 skip "server does not support overstriping"
2427         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2428         large_xattr_enabled || skip_env "ea_inode feature disabled"
2429
2430         test_mkdir -p $DIR/$tdir
2431         local setcount=$LOV_MAX_STRIPE_COUNT
2432
2433         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2434                 error "setstripe failed"
2435
2436         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2437         [ $count -eq $setcount ] ||
2438                 error "stripe count $count, should be $setcount"
2439
2440         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2441                 error "overstriped should be set in pattern"
2442
2443         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2444                 error "dd failed"
2445
2446         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2447 }
2448 run_test 27Cd "test maximum stripe count"
2449
2450 test_27Ce() {
2451         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2452                 skip "server does not support overstriping"
2453         test_mkdir -p $DIR/$tdir
2454
2455         pool_add $TESTNAME || error "Pool creation failed"
2456         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2457
2458         local setcount=8
2459
2460         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2461                 error "setstripe failed"
2462
2463         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2464         [ $count -eq $setcount ] ||
2465                 error "stripe count $count, should be $setcount"
2466
2467         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2468                 error "overstriped should be set in pattern"
2469
2470         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2471                 error "dd failed"
2472
2473         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2474 }
2475 run_test 27Ce "test pool with overstriping"
2476
2477 test_27Cf() {
2478         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2479                 skip "server does not support overstriping"
2480         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2481                 skip_env "too many osts, skipping"
2482
2483         test_mkdir -p $DIR/$tdir
2484
2485         local setcount=$(($OSTCOUNT * 2))
2486         [ $setcount -ge 160 ] || large_xattr_enabled ||
2487                 skip_env "ea_inode feature disabled"
2488
2489         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2490                 error "setstripe failed"
2491
2492         echo 1 > $DIR/$tdir/$tfile
2493
2494         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2495         [ $count -eq $setcount ] ||
2496                 error "stripe count $count, should be $setcount"
2497
2498         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2499                 error "overstriped should be set in pattern"
2500
2501         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2502                 error "dd failed"
2503
2504         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2505 }
2506 run_test 27Cf "test default inheritance with overstriping"
2507
2508 test_27D() {
2509         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2510         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2511         remote_mds_nodsh && skip "remote MDS with nodsh"
2512
2513         local POOL=${POOL:-testpool}
2514         local first_ost=0
2515         local last_ost=$(($OSTCOUNT - 1))
2516         local ost_step=1
2517         local ost_list=$(seq $first_ost $ost_step $last_ost)
2518         local ost_range="$first_ost $last_ost $ost_step"
2519
2520         test_mkdir $DIR/$tdir
2521         pool_add $POOL || error "pool_add failed"
2522         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2523
2524         local skip27D
2525         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2526                 skip27D+="-s 29"
2527         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2528                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2529                         skip27D+=" -s 30,31"
2530         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2531           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2532                 skip27D+=" -s 32,33"
2533         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2534                 skip27D+=" -s 34"
2535         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2536                 error "llapi_layout_test failed"
2537
2538         destroy_test_pools || error "destroy test pools failed"
2539 }
2540 run_test 27D "validate llapi_layout API"
2541
2542 # Verify that default_easize is increased from its initial value after
2543 # accessing a widely striped file.
2544 test_27E() {
2545         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2546         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2547                 skip "client does not have LU-3338 fix"
2548
2549         # 72 bytes is the minimum space required to store striping
2550         # information for a file striped across one OST:
2551         # (sizeof(struct lov_user_md_v3) +
2552         #  sizeof(struct lov_user_ost_data_v1))
2553         local min_easize=72
2554         $LCTL set_param -n llite.*.default_easize $min_easize ||
2555                 error "lctl set_param failed"
2556         local easize=$($LCTL get_param -n llite.*.default_easize)
2557
2558         [ $easize -eq $min_easize ] ||
2559                 error "failed to set default_easize"
2560
2561         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2562                 error "setstripe failed"
2563         # In order to ensure stat() call actually talks to MDS we need to
2564         # do something drastic to this file to shake off all lock, e.g.
2565         # rename it (kills lookup lock forcing cache cleaning)
2566         mv $DIR/$tfile $DIR/${tfile}-1
2567         ls -l $DIR/${tfile}-1
2568         rm $DIR/${tfile}-1
2569
2570         easize=$($LCTL get_param -n llite.*.default_easize)
2571
2572         [ $easize -gt $min_easize ] ||
2573                 error "default_easize not updated"
2574 }
2575 run_test 27E "check that default extended attribute size properly increases"
2576
2577 test_27F() { # LU-5346/LU-7975
2578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2579         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2580         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2581                 skip "Need MDS version at least 2.8.51"
2582         remote_ost_nodsh && skip "remote OST with nodsh"
2583
2584         test_mkdir $DIR/$tdir
2585         rm -f $DIR/$tdir/f0
2586         $LFS setstripe -c 2 $DIR/$tdir
2587
2588         # stop all OSTs to reproduce situation for LU-7975 ticket
2589         for num in $(seq $OSTCOUNT); do
2590                 stop ost$num
2591         done
2592
2593         # open/create f0 with O_LOV_DELAY_CREATE
2594         # truncate f0 to a non-0 size
2595         # close
2596         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2597
2598         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2599         # open/write it again to force delayed layout creation
2600         cat /etc/hosts > $DIR/$tdir/f0 &
2601         catpid=$!
2602
2603         # restart OSTs
2604         for num in $(seq $OSTCOUNT); do
2605                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2606                         error "ost$num failed to start"
2607         done
2608
2609         wait $catpid || error "cat failed"
2610
2611         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2612         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2613                 error "wrong stripecount"
2614
2615 }
2616 run_test 27F "Client resend delayed layout creation with non-zero size"
2617
2618 test_27G() { #LU-10629
2619         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2620                 skip "Need MDS version at least 2.11.51"
2621         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2622         remote_mds_nodsh && skip "remote MDS with nodsh"
2623         local POOL=${POOL:-testpool}
2624         local ostrange="0 0 1"
2625
2626         test_mkdir $DIR/$tdir
2627         touch $DIR/$tdir/$tfile.nopool
2628         pool_add $POOL || error "pool_add failed"
2629         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2630         $LFS setstripe -p $POOL $DIR/$tdir
2631
2632         local pool=$($LFS getstripe -p $DIR/$tdir)
2633
2634         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2635         touch $DIR/$tdir/$tfile.default
2636         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2637         $LFS find $DIR/$tdir -type f --pool $POOL
2638         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2639         [[ "$found" == "2" ]] ||
2640                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2641
2642         $LFS setstripe -d $DIR/$tdir
2643
2644         pool=$($LFS getstripe -p -d $DIR/$tdir)
2645
2646         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2647 }
2648 run_test 27G "Clear OST pool from stripe"
2649
2650 test_27H() {
2651         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2652                 skip "Need MDS version newer than 2.11.54"
2653         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2654         test_mkdir $DIR/$tdir
2655         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2656         touch $DIR/$tdir/$tfile
2657         $LFS getstripe -c $DIR/$tdir/$tfile
2658         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2659                 error "two-stripe file doesn't have two stripes"
2660
2661         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2662         $LFS getstripe -y $DIR/$tdir/$tfile
2663         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2664              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2665                 error "expected l_ost_idx: [02]$ not matched"
2666
2667         # make sure ost list has been cleared
2668         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2669         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2670                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2671         touch $DIR/$tdir/f3
2672         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2673 }
2674 run_test 27H "Set specific OSTs stripe"
2675
2676 test_27I() {
2677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2678         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2679         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2680                 skip "Need MDS version newer than 2.12.52"
2681         local pool=$TESTNAME
2682         local ostrange="1 1 1"
2683
2684         save_layout_restore_at_exit $MOUNT
2685         $LFS setstripe -c 2 -i 0 $MOUNT
2686         pool_add $pool || error "pool_add failed"
2687         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2688         test_mkdir $DIR/$tdir
2689         $LFS setstripe -p $pool $DIR/$tdir
2690         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2691         $LFS getstripe $DIR/$tdir/$tfile
2692 }
2693 run_test 27I "check that root dir striping does not break parent dir one"
2694
2695 test_27J() {
2696         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2697                 skip "Need MDS version newer than 2.12.51"
2698
2699         test_mkdir $DIR/$tdir
2700         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2701         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2702
2703         # create foreign file (raw way)
2704         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2705                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2706
2707         # verify foreign file (raw way)
2708         parse_foreign_file -f $DIR/$tdir/$tfile |
2709                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2710                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2711         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2712                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2713         parse_foreign_file -f $DIR/$tdir/$tfile |
2714                 grep "lov_foreign_size: 73" ||
2715                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2716         parse_foreign_file -f $DIR/$tdir/$tfile |
2717                 grep "lov_foreign_type: 1" ||
2718                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2719         parse_foreign_file -f $DIR/$tdir/$tfile |
2720                 grep "lov_foreign_flags: 0x0000DA08" ||
2721                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2722         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2723                 grep "lov_foreign_value: 0x" |
2724                 sed -e 's/lov_foreign_value: 0x//')
2725         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2726         [[ $lov = ${lov2// /} ]] ||
2727                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2728
2729         # create foreign file (lfs + API)
2730         $LFS setstripe --foreign=daos --flags 0xda08 \
2731                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2732                 error "$DIR/$tdir/${tfile}2: create failed"
2733
2734         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2735                 grep "lfm_magic:.*0x0BD70BD0" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2737         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2738         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2739                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2740         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2741                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2742         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2743                 grep "lfm_flags:.*0x0000DA08" ||
2744                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2745         $LFS getstripe $DIR/$tdir/${tfile}2 |
2746                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2747                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2748
2749         # modify striping should fail
2750         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2751                 error "$DIR/$tdir/$tfile: setstripe should fail"
2752         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2753                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2754
2755         # R/W should fail
2756         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2757         cat $DIR/$tdir/${tfile}2 &&
2758                 error "$DIR/$tdir/${tfile}2: read should fail"
2759         cat /etc/passwd > $DIR/$tdir/$tfile &&
2760                 error "$DIR/$tdir/$tfile: write should fail"
2761         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2762                 error "$DIR/$tdir/${tfile}2: write should fail"
2763
2764         # chmod should work
2765         chmod 222 $DIR/$tdir/$tfile ||
2766                 error "$DIR/$tdir/$tfile: chmod failed"
2767         chmod 222 $DIR/$tdir/${tfile}2 ||
2768                 error "$DIR/$tdir/${tfile}2: chmod failed"
2769
2770         # chown should work
2771         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2772                 error "$DIR/$tdir/$tfile: chown failed"
2773         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2774                 error "$DIR/$tdir/${tfile}2: chown failed"
2775
2776         # rename should work
2777         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2778                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2779         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2780                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2781
2782         #remove foreign file
2783         rm $DIR/$tdir/${tfile}.new ||
2784                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2785         rm $DIR/$tdir/${tfile}2.new ||
2786                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2787 }
2788 run_test 27J "basic ops on file with foreign LOV"
2789
2790 test_27K() {
2791         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2792                 skip "Need MDS version newer than 2.12.49"
2793
2794         test_mkdir $DIR/$tdir
2795         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2796         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2797
2798         # create foreign dir (raw way)
2799         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2800                 error "create_foreign_dir FAILED"
2801
2802         # verify foreign dir (raw way)
2803         parse_foreign_dir -d $DIR/$tdir/$tdir |
2804                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2805                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2806         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2807                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2808         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2809                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2810         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2811                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2812         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2813                 grep "lmv_foreign_value: 0x" |
2814                 sed 's/lmv_foreign_value: 0x//')
2815         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2816                 sed 's/ //g')
2817         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2818
2819         # create foreign dir (lfs + API)
2820         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2821                 $DIR/$tdir/${tdir}2 ||
2822                 error "$DIR/$tdir/${tdir}2: create failed"
2823
2824         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2825                 grep "lfm_magic:.*0x0CD50CD0" ||
2826                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2827         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2828         # - sizeof(lfm_type) - sizeof(lfm_flags)
2829         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2830                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2831         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2832                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2833         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2834                 grep "lfm_flags:.*0x0000DA05" ||
2835                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2836         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2837                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2838                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2839
2840         # file create in dir should fail
2841         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2842         touch $DIR/$tdir/${tdir}2/$tfile &&
2843                 "$DIR/${tdir}2: file create should fail"
2844
2845         # chmod should work
2846         chmod 777 $DIR/$tdir/$tdir ||
2847                 error "$DIR/$tdir: chmod failed"
2848         chmod 777 $DIR/$tdir/${tdir}2 ||
2849                 error "$DIR/${tdir}2: chmod failed"
2850
2851         # chown should work
2852         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2853                 error "$DIR/$tdir: chown failed"
2854         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2855                 error "$DIR/${tdir}2: chown failed"
2856
2857         # rename should work
2858         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2859                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2860         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2861                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2862
2863         #remove foreign dir
2864         rmdir $DIR/$tdir/${tdir}.new ||
2865                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2866         rmdir $DIR/$tdir/${tdir}2.new ||
2867                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2868 }
2869 run_test 27K "basic ops on dir with foreign LMV"
2870
2871 test_27L() {
2872         remote_mds_nodsh && skip "remote MDS with nodsh"
2873
2874         local POOL=${POOL:-$TESTNAME}
2875
2876         pool_add $POOL || error "pool_add failed"
2877
2878         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2879                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2880                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2881 }
2882 run_test 27L "lfs pool_list gives correct pool name"
2883
2884 test_27M() {
2885         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2886                 skip "Need MDS version >= than 2.12.57"
2887         remote_mds_nodsh && skip "remote MDS with nodsh"
2888         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2889
2890         test_mkdir $DIR/$tdir
2891
2892         # Set default striping on directory
2893         $LFS setstripe -C 4 $DIR/$tdir
2894
2895         echo 1 > $DIR/$tdir/${tfile}.1
2896         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2897         local setcount=4
2898         [ $count -eq $setcount ] ||
2899                 error "(1) stripe count $count, should be $setcount"
2900
2901         # Capture existing append_stripe_count setting for restore
2902         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2903         local mdts=$(comma_list $(mdts_nodes))
2904         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2905
2906         local appendcount=$orig_count
2907         echo 1 >> $DIR/$tdir/${tfile}.2_append
2908         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2909         [ $count -eq $appendcount ] ||
2910                 error "(2)stripe count $count, should be $appendcount for append"
2911
2912         # Disable O_APPEND striping, verify it works
2913         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2914
2915         # Should now get the default striping, which is 4
2916         setcount=4
2917         echo 1 >> $DIR/$tdir/${tfile}.3_append
2918         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2919         [ $count -eq $setcount ] ||
2920                 error "(3) stripe count $count, should be $setcount"
2921
2922         # Try changing the stripe count for append files
2923         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2924
2925         # Append striping is now 2 (directory default is still 4)
2926         appendcount=2
2927         echo 1 >> $DIR/$tdir/${tfile}.4_append
2928         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2929         [ $count -eq $appendcount ] ||
2930                 error "(4) stripe count $count, should be $appendcount for append"
2931
2932         # Test append stripe count of -1
2933         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2934         appendcount=$OSTCOUNT
2935         echo 1 >> $DIR/$tdir/${tfile}.5
2936         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2937         [ $count -eq $appendcount ] ||
2938                 error "(5) stripe count $count, should be $appendcount for append"
2939
2940         # Set append striping back to default of 1
2941         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2942
2943         # Try a new default striping, PFL + DOM
2944         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2945
2946         # Create normal DOM file, DOM returns stripe count == 0
2947         setcount=0
2948         touch $DIR/$tdir/${tfile}.6
2949         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2950         [ $count -eq $setcount ] ||
2951                 error "(6) stripe count $count, should be $setcount"
2952
2953         # Show
2954         appendcount=1
2955         echo 1 >> $DIR/$tdir/${tfile}.7_append
2956         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2957         [ $count -eq $appendcount ] ||
2958                 error "(7) stripe count $count, should be $appendcount for append"
2959
2960         # Clean up DOM layout
2961         $LFS setstripe -d $DIR/$tdir
2962
2963         # Now test that append striping works when layout is from root
2964         $LFS setstripe -c 2 $MOUNT
2965         # Make a special directory for this
2966         mkdir $DIR/${tdir}/${tdir}.2
2967         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2968
2969         # Verify for normal file
2970         setcount=2
2971         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2972         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2973         [ $count -eq $setcount ] ||
2974                 error "(8) stripe count $count, should be $setcount"
2975
2976         appendcount=1
2977         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2978         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2979         [ $count -eq $appendcount ] ||
2980                 error "(9) stripe count $count, should be $appendcount for append"
2981
2982         # Now test O_APPEND striping with pools
2983         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2984         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2985
2986         # Create the pool
2987         pool_add $TESTNAME || error "pool creation failed"
2988         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2989
2990         echo 1 >> $DIR/$tdir/${tfile}.10_append
2991
2992         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2993         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2994
2995         # Check that count is still correct
2996         appendcount=1
2997         echo 1 >> $DIR/$tdir/${tfile}.11_append
2998         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2999         [ $count -eq $appendcount ] ||
3000                 error "(11) stripe count $count, should be $appendcount for append"
3001
3002         # Disable O_APPEND stripe count, verify pool works separately
3003         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3004
3005         echo 1 >> $DIR/$tdir/${tfile}.12_append
3006
3007         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3008         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3009
3010         # Remove pool setting, verify it's not applied
3011         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3012
3013         echo 1 >> $DIR/$tdir/${tfile}.13_append
3014
3015         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3016         [ "$pool" = "" ] || error "(13) pool found: $pool"
3017 }
3018 run_test 27M "test O_APPEND striping"
3019
3020 test_27N() {
3021         combined_mgs_mds && skip "needs separate MGS/MDT"
3022
3023         pool_add $TESTNAME || error "pool_add failed"
3024         do_facet mgs "$LCTL pool_list $FSNAME" |
3025                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3026                 error "lctl pool_list on MGS failed"
3027 }
3028 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3029
3030 # createtest also checks that device nodes are created and
3031 # then visible correctly (#2091)
3032 test_28() { # bug 2091
3033         test_mkdir $DIR/d28
3034         $CREATETEST $DIR/d28/ct || error "createtest failed"
3035 }
3036 run_test 28 "create/mknod/mkdir with bad file types ============"
3037
3038 test_29() {
3039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3040
3041         sync; sleep 1; sync # flush out any dirty pages from previous tests
3042         cancel_lru_locks
3043         test_mkdir $DIR/d29
3044         touch $DIR/d29/foo
3045         log 'first d29'
3046         ls -l $DIR/d29
3047
3048         declare -i LOCKCOUNTORIG=0
3049         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3050                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3051         done
3052         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3053
3054         declare -i LOCKUNUSEDCOUNTORIG=0
3055         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3056                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3057         done
3058
3059         log 'second d29'
3060         ls -l $DIR/d29
3061         log 'done'
3062
3063         declare -i LOCKCOUNTCURRENT=0
3064         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3065                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3066         done
3067
3068         declare -i LOCKUNUSEDCOUNTCURRENT=0
3069         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3070                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3071         done
3072
3073         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3074                 $LCTL set_param -n ldlm.dump_namespaces ""
3075                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3076                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3077                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3078                 return 2
3079         fi
3080         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3081                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3082                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3083                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3084                 return 3
3085         fi
3086 }
3087 run_test 29 "IT_GETATTR regression  ============================"
3088
3089 test_30a() { # was test_30
3090         cp $(which ls) $DIR || cp /bin/ls $DIR
3091         $DIR/ls / || error "Can't execute binary from lustre"
3092         rm $DIR/ls
3093 }
3094 run_test 30a "execute binary from Lustre (execve) =============="
3095
3096 test_30b() {
3097         cp `which ls` $DIR || cp /bin/ls $DIR
3098         chmod go+rx $DIR/ls
3099         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3100         rm $DIR/ls
3101 }
3102 run_test 30b "execute binary from Lustre as non-root ==========="
3103
3104 test_30c() { # b=22376
3105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3106
3107         cp $(which ls) $DIR || cp /bin/ls $DIR
3108         chmod a-rw $DIR/ls
3109         cancel_lru_locks mdc
3110         cancel_lru_locks osc
3111         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3112         rm -f $DIR/ls
3113 }
3114 run_test 30c "execute binary from Lustre without read perms ===="
3115
3116 test_30d() {
3117         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3118
3119         for i in {1..10}; do
3120                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3121                 local PID=$!
3122                 sleep 1
3123                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3124                 wait $PID || error "executing dd from Lustre failed"
3125                 rm -f $DIR/$tfile
3126         done
3127
3128         rm -f $DIR/dd
3129 }
3130 run_test 30d "execute binary from Lustre while clear locks"
3131
3132 test_31a() {
3133         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3134         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3135 }
3136 run_test 31a "open-unlink file =================================="
3137
3138 test_31b() {
3139         touch $DIR/f31 || error "touch $DIR/f31 failed"
3140         ln $DIR/f31 $DIR/f31b || error "ln failed"
3141         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3142         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3143 }
3144 run_test 31b "unlink file with multiple links while open ======="
3145
3146 test_31c() {
3147         touch $DIR/f31 || error "touch $DIR/f31 failed"
3148         ln $DIR/f31 $DIR/f31c || error "ln failed"
3149         multiop_bg_pause $DIR/f31 O_uc ||
3150                 error "multiop_bg_pause for $DIR/f31 failed"
3151         MULTIPID=$!
3152         $MULTIOP $DIR/f31c Ouc
3153         kill -USR1 $MULTIPID
3154         wait $MULTIPID
3155 }
3156 run_test 31c "open-unlink file with multiple links ============="
3157
3158 test_31d() {
3159         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3160         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3161 }
3162 run_test 31d "remove of open directory ========================="
3163
3164 test_31e() { # bug 2904
3165         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3166 }
3167 run_test 31e "remove of open non-empty directory ==============="
3168
3169 test_31f() { # bug 4554
3170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3171
3172         set -vx
3173         test_mkdir $DIR/d31f
3174         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3175         cp /etc/hosts $DIR/d31f
3176         ls -l $DIR/d31f
3177         $LFS getstripe $DIR/d31f/hosts
3178         multiop_bg_pause $DIR/d31f D_c || return 1
3179         MULTIPID=$!
3180
3181         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3182         test_mkdir $DIR/d31f
3183         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3184         cp /etc/hosts $DIR/d31f
3185         ls -l $DIR/d31f
3186         $LFS getstripe $DIR/d31f/hosts
3187         multiop_bg_pause $DIR/d31f D_c || return 1
3188         MULTIPID2=$!
3189
3190         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3191         wait $MULTIPID || error "first opendir $MULTIPID failed"
3192
3193         sleep 6
3194
3195         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3196         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3197         set +vx
3198 }
3199 run_test 31f "remove of open directory with open-unlink file ==="
3200
3201 test_31g() {
3202         echo "-- cross directory link --"
3203         test_mkdir -c1 $DIR/${tdir}ga
3204         test_mkdir -c1 $DIR/${tdir}gb
3205         touch $DIR/${tdir}ga/f
3206         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3207         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3208         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3209         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3210         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3211 }
3212 run_test 31g "cross directory link==============="
3213
3214 test_31h() {
3215         echo "-- cross directory link --"
3216         test_mkdir -c1 $DIR/${tdir}
3217         test_mkdir -c1 $DIR/${tdir}/dir
3218         touch $DIR/${tdir}/f
3219         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3220         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3221         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3222         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3223         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3224 }
3225 run_test 31h "cross directory link under child==============="
3226
3227 test_31i() {
3228         echo "-- cross directory link --"
3229         test_mkdir -c1 $DIR/$tdir
3230         test_mkdir -c1 $DIR/$tdir/dir
3231         touch $DIR/$tdir/dir/f
3232         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3233         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3234         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3235         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3236         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3237 }
3238 run_test 31i "cross directory link under parent==============="
3239
3240 test_31j() {
3241         test_mkdir -c1 -p $DIR/$tdir
3242         test_mkdir -c1 -p $DIR/$tdir/dir1
3243         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3244         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3245         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3246         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3247         return 0
3248 }
3249 run_test 31j "link for directory==============="
3250
3251 test_31k() {
3252         test_mkdir -c1 -p $DIR/$tdir
3253         touch $DIR/$tdir/s
3254         touch $DIR/$tdir/exist
3255         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3256         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3257         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3258         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3259         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3260         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3261         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3262         return 0
3263 }
3264 run_test 31k "link to file: the same, non-existing, dir==============="
3265
3266 test_31m() {
3267         mkdir $DIR/d31m
3268         touch $DIR/d31m/s
3269         mkdir $DIR/d31m2
3270         touch $DIR/d31m2/exist
3271         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3272         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3273         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3274         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3275         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3276         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3277         return 0
3278 }
3279 run_test 31m "link to file: the same, non-existing, dir==============="
3280
3281 test_31n() {
3282         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3283         nlink=$(stat --format=%h $DIR/$tfile)
3284         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3285         local fd=$(free_fd)
3286         local cmd="exec $fd<$DIR/$tfile"
3287         eval $cmd
3288         cmd="exec $fd<&-"
3289         trap "eval $cmd" EXIT
3290         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3291         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3292         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3293         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3294         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3295         eval $cmd
3296 }
3297 run_test 31n "check link count of unlinked file"
3298
3299 link_one() {
3300         local tempfile=$(mktemp $1_XXXXXX)
3301         mlink $tempfile $1 2> /dev/null &&
3302                 echo "$BASHPID: link $tempfile to $1 succeeded"
3303         munlink $tempfile
3304 }
3305
3306 test_31o() { # LU-2901
3307         test_mkdir $DIR/$tdir
3308         for LOOP in $(seq 100); do
3309                 rm -f $DIR/$tdir/$tfile*
3310                 for THREAD in $(seq 8); do
3311                         link_one $DIR/$tdir/$tfile.$LOOP &
3312                 done
3313                 wait
3314                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3315                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3316                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3317                         break || true
3318         done
3319 }
3320 run_test 31o "duplicate hard links with same filename"
3321
3322 test_31p() {
3323         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3324
3325         test_mkdir $DIR/$tdir
3326         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3327         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3328
3329         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3330                 error "open unlink test1 failed"
3331         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3332                 error "open unlink test2 failed"
3333
3334         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3335                 error "test1 still exists"
3336         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3337                 error "test2 still exists"
3338 }
3339 run_test 31p "remove of open striped directory"
3340
3341 cleanup_test32_mount() {
3342         local rc=0
3343         trap 0
3344         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3345         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3346         losetup -d $loopdev || true
3347         rm -rf $DIR/$tdir
3348         return $rc
3349 }
3350
3351 test_32a() {
3352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3353
3354         echo "== more mountpoints and symlinks ================="
3355         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3356         trap cleanup_test32_mount EXIT
3357         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3358         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3359                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3360         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3361                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3362         cleanup_test32_mount
3363 }
3364 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3365
3366 test_32b() {
3367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3368
3369         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3370         trap cleanup_test32_mount EXIT
3371         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3372         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3373                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3374         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3375                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3376         cleanup_test32_mount
3377 }
3378 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3379
3380 test_32c() {
3381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3382
3383         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3384         trap cleanup_test32_mount EXIT
3385         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3386         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3387                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3388         test_mkdir -p $DIR/$tdir/d2/test_dir
3389         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3390                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3391         cleanup_test32_mount
3392 }
3393 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3394
3395 test_32d() {
3396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3397
3398         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3399         trap cleanup_test32_mount EXIT
3400         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3401         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3402                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3403         test_mkdir -p $DIR/$tdir/d2/test_dir
3404         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3405                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3406         cleanup_test32_mount
3407 }
3408 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3409
3410 test_32e() {
3411         rm -fr $DIR/$tdir
3412         test_mkdir -p $DIR/$tdir/tmp
3413         local tmp_dir=$DIR/$tdir/tmp
3414         ln -s $DIR/$tdir $tmp_dir/symlink11
3415         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3416         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3417         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3418 }
3419 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3420
3421 test_32f() {
3422         rm -fr $DIR/$tdir
3423         test_mkdir -p $DIR/$tdir/tmp
3424         local tmp_dir=$DIR/$tdir/tmp
3425         ln -s $DIR/$tdir $tmp_dir/symlink11
3426         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3427         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3428         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3429 }
3430 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3431
3432 test_32g() {
3433         local tmp_dir=$DIR/$tdir/tmp
3434         test_mkdir -p $tmp_dir
3435         test_mkdir $DIR/${tdir}2
3436         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3437         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3438         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3439         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3440         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3441         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3442 }
3443 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3444
3445 test_32h() {
3446         rm -fr $DIR/$tdir $DIR/${tdir}2
3447         tmp_dir=$DIR/$tdir/tmp
3448         test_mkdir -p $tmp_dir
3449         test_mkdir $DIR/${tdir}2
3450         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3451         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3452         ls $tmp_dir/symlink12 || error "listing symlink12"
3453         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3454 }
3455 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3456
3457 test_32i() {
3458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3459
3460         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3461         trap cleanup_test32_mount EXIT
3462         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3463         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3464                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3465         touch $DIR/$tdir/test_file
3466         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3467                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3468         cleanup_test32_mount
3469 }
3470 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3471
3472 test_32j() {
3473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3474
3475         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3476         trap cleanup_test32_mount EXIT
3477         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3478         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3479                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3480         touch $DIR/$tdir/test_file
3481         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3482                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3483         cleanup_test32_mount
3484 }
3485 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3486
3487 test_32k() {
3488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3489
3490         rm -fr $DIR/$tdir
3491         trap cleanup_test32_mount EXIT
3492         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3493         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3494                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3495         test_mkdir -p $DIR/$tdir/d2
3496         touch $DIR/$tdir/d2/test_file || error "touch failed"
3497         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3498                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3499         cleanup_test32_mount
3500 }
3501 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3502
3503 test_32l() {
3504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3505
3506         rm -fr $DIR/$tdir
3507         trap cleanup_test32_mount EXIT
3508         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3509         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3510                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3511         test_mkdir -p $DIR/$tdir/d2
3512         touch $DIR/$tdir/d2/test_file || error "touch failed"
3513         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3514                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3515         cleanup_test32_mount
3516 }
3517 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3518
3519 test_32m() {
3520         rm -fr $DIR/d32m
3521         test_mkdir -p $DIR/d32m/tmp
3522         TMP_DIR=$DIR/d32m/tmp
3523         ln -s $DIR $TMP_DIR/symlink11
3524         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3525         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3526                 error "symlink11 not a link"
3527         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3528                 error "symlink01 not a link"
3529 }
3530 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3531
3532 test_32n() {
3533         rm -fr $DIR/d32n
3534         test_mkdir -p $DIR/d32n/tmp
3535         TMP_DIR=$DIR/d32n/tmp
3536         ln -s $DIR $TMP_DIR/symlink11
3537         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3538         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3539         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3540 }
3541 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3542
3543 test_32o() {
3544         touch $DIR/$tfile
3545         test_mkdir -p $DIR/d32o/tmp
3546         TMP_DIR=$DIR/d32o/tmp
3547         ln -s $DIR/$tfile $TMP_DIR/symlink12
3548         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3549         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3550                 error "symlink12 not a link"
3551         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3552         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3553                 error "$DIR/d32o/tmp/symlink12 not file type"
3554         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3555                 error "$DIR/d32o/symlink02 not file type"
3556 }
3557 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3558
3559 test_32p() {
3560         log 32p_1
3561         rm -fr $DIR/d32p
3562         log 32p_2
3563         rm -f $DIR/$tfile
3564         log 32p_3
3565         touch $DIR/$tfile
3566         log 32p_4
3567         test_mkdir -p $DIR/d32p/tmp
3568         log 32p_5
3569         TMP_DIR=$DIR/d32p/tmp
3570         log 32p_6
3571         ln -s $DIR/$tfile $TMP_DIR/symlink12
3572         log 32p_7
3573         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3574         log 32p_8
3575         cat $DIR/d32p/tmp/symlink12 ||
3576                 error "Can't open $DIR/d32p/tmp/symlink12"
3577         log 32p_9
3578         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3579         log 32p_10
3580 }
3581 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3582
3583 test_32q() {
3584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3585
3586         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3587         trap cleanup_test32_mount EXIT
3588         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3589         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3590         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3591                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3592         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3593         cleanup_test32_mount
3594 }
3595 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3596
3597 test_32r() {
3598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3599
3600         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3601         trap cleanup_test32_mount EXIT
3602         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3603         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3604         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3605                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3606         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3607         cleanup_test32_mount
3608 }
3609 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3610
3611 test_33aa() {
3612         rm -f $DIR/$tfile
3613         touch $DIR/$tfile
3614         chmod 444 $DIR/$tfile
3615         chown $RUNAS_ID $DIR/$tfile
3616         log 33_1
3617         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3618         log 33_2
3619 }
3620 run_test 33aa "write file with mode 444 (should return error)"
3621
3622 test_33a() {
3623         rm -fr $DIR/$tdir
3624         test_mkdir $DIR/$tdir
3625         chown $RUNAS_ID $DIR/$tdir
3626         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3627                 error "$RUNAS create $tdir/$tfile failed"
3628         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3629                 error "open RDWR" || true
3630 }
3631 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3632
3633 test_33b() {
3634         rm -fr $DIR/$tdir
3635         test_mkdir $DIR/$tdir
3636         chown $RUNAS_ID $DIR/$tdir
3637         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3638 }
3639 run_test 33b "test open file with malformed flags (No panic)"
3640
3641 test_33c() {
3642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3643         remote_ost_nodsh && skip "remote OST with nodsh"
3644
3645         local ostnum
3646         local ostname
3647         local write_bytes
3648         local all_zeros
3649
3650         all_zeros=:
3651         rm -fr $DIR/$tdir
3652         test_mkdir $DIR/$tdir
3653         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3654
3655         sync
3656         for ostnum in $(seq $OSTCOUNT); do
3657                 # test-framework's OST numbering is one-based, while Lustre's
3658                 # is zero-based
3659                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3660                 # Parsing llobdstat's output sucks; we could grep the /proc
3661                 # path, but that's likely to not be as portable as using the
3662                 # llobdstat utility.  So we parse lctl output instead.
3663                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3664                         obdfilter/$ostname/stats |
3665                         awk '/^write_bytes/ {print $7}' )
3666                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3667                 if (( ${write_bytes:-0} > 0 ))
3668                 then
3669                         all_zeros=false
3670                         break;
3671                 fi
3672         done
3673
3674         $all_zeros || return 0
3675
3676         # Write four bytes
3677         echo foo > $DIR/$tdir/bar
3678         # Really write them
3679         sync
3680
3681         # Total up write_bytes after writing.  We'd better find non-zeros.
3682         for ostnum in $(seq $OSTCOUNT); do
3683                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3684                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3685                         obdfilter/$ostname/stats |
3686                         awk '/^write_bytes/ {print $7}' )
3687                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3688                 if (( ${write_bytes:-0} > 0 ))
3689                 then
3690                         all_zeros=false
3691                         break;
3692                 fi
3693         done
3694
3695         if $all_zeros
3696         then
3697                 for ostnum in $(seq $OSTCOUNT); do
3698                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3699                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3700                         do_facet ost$ostnum lctl get_param -n \
3701                                 obdfilter/$ostname/stats
3702                 done
3703                 error "OST not keeping write_bytes stats (b22312)"
3704         fi
3705 }
3706 run_test 33c "test llobdstat and write_bytes"
3707
3708 test_33d() {
3709         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3711
3712         local MDTIDX=1
3713         local remote_dir=$DIR/$tdir/remote_dir
3714
3715         test_mkdir $DIR/$tdir
3716         $LFS mkdir -i $MDTIDX $remote_dir ||
3717                 error "create remote directory failed"
3718
3719         touch $remote_dir/$tfile
3720         chmod 444 $remote_dir/$tfile
3721         chown $RUNAS_ID $remote_dir/$tfile
3722
3723         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3724
3725         chown $RUNAS_ID $remote_dir
3726         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3727                                         error "create" || true
3728         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3729                                     error "open RDWR" || true
3730         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3731 }
3732 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3733
3734 test_33e() {
3735         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3736
3737         mkdir $DIR/$tdir
3738
3739         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3740         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3741         mkdir $DIR/$tdir/local_dir
3742
3743         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3744         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3745         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3746
3747         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3748                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3749
3750         rmdir $DIR/$tdir/* || error "rmdir failed"
3751
3752         umask 777
3753         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3754         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3755         mkdir $DIR/$tdir/local_dir
3756
3757         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3758         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3759         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3760
3761         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3762                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3763
3764         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3765
3766         umask 000
3767         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3768         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3769         mkdir $DIR/$tdir/local_dir
3770
3771         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3772         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3773         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3774
3775         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3776                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3777 }
3778 run_test 33e "mkdir and striped directory should have same mode"
3779
3780 cleanup_33f() {
3781         trap 0
3782         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3783 }
3784
3785 test_33f() {
3786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3787         remote_mds_nodsh && skip "remote MDS with nodsh"
3788
3789         mkdir $DIR/$tdir
3790         chmod go+rwx $DIR/$tdir
3791         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3792         trap cleanup_33f EXIT
3793
3794         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3795                 error "cannot create striped directory"
3796
3797         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3798                 error "cannot create files in striped directory"
3799
3800         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3801                 error "cannot remove files in striped directory"
3802
3803         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3804                 error "cannot remove striped directory"
3805
3806         cleanup_33f
3807 }
3808 run_test 33f "nonroot user can create, access, and remove a striped directory"
3809
3810 test_33g() {
3811         mkdir -p $DIR/$tdir/dir2
3812
3813         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3814         echo $err
3815         [[ $err =~ "exists" ]] || error "Not exists error"
3816 }
3817 run_test 33g "nonroot user create already existing root created file"
3818
3819 test_33h() {
3820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3821         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3822                 skip "Need MDS version at least 2.13.50"
3823
3824         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3825                 error "mkdir $tdir failed"
3826         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3827
3828         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3829         local index2
3830
3831         for fname in $DIR/$tdir/$tfile.bak \
3832                      $DIR/$tdir/$tfile.SAV \
3833                      $DIR/$tdir/$tfile.orig \
3834                      $DIR/$tdir/$tfile~; do
3835                 touch $fname  || error "touch $fname failed"
3836                 index2=$($LFS getstripe -m $fname)
3837                 [ $index -eq $index2 ] ||
3838                         error "$fname MDT index mismatch $index != $index2"
3839         done
3840
3841         local failed=0
3842         for i in {1..250}; do
3843                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3844                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3845                         touch $fname  || error "touch $fname failed"
3846                         index2=$($LFS getstripe -m $fname)
3847                         if [[ $index != $index2 ]]; then
3848                                 failed=$((failed + 1))
3849                                 echo "$fname MDT index mismatch $index != $index2"
3850                         fi
3851                 done
3852         done
3853         echo "$failed MDT index mismatches"
3854         (( failed < 20 )) || error "MDT index mismatch $failed times"
3855
3856 }
3857 run_test 33h "temp file is located on the same MDT as target"
3858
3859 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3860 test_34a() {
3861         rm -f $DIR/f34
3862         $MCREATE $DIR/f34 || error "mcreate failed"
3863         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3864                 error "getstripe failed"
3865         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3866         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3867                 error "getstripe failed"
3868         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3869                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3870 }
3871 run_test 34a "truncate file that has not been opened ==========="
3872
3873 test_34b() {
3874         [ ! -f $DIR/f34 ] && test_34a
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877         $OPENFILE -f O_RDONLY $DIR/f34
3878         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3879                 error "getstripe failed"
3880         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3881                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3882 }
3883 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3884
3885 test_34c() {
3886         [ ! -f $DIR/f34 ] && test_34a
3887         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3888                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3889         $OPENFILE -f O_RDWR $DIR/f34
3890         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3891                 error "$LFS getstripe failed"
3892         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3893                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3894 }
3895 run_test 34c "O_RDWR opening file-with-size works =============="
3896
3897 test_34d() {
3898         [ ! -f $DIR/f34 ] && test_34a
3899         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3900                 error "dd failed"
3901         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3902                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3903         rm $DIR/f34
3904 }
3905 run_test 34d "write to sparse file ============================="
3906
3907 test_34e() {
3908         rm -f $DIR/f34e
3909         $MCREATE $DIR/f34e || error "mcreate failed"
3910         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3911         $CHECKSTAT -s 1000 $DIR/f34e ||
3912                 error "Size of $DIR/f34e not equal to 1000 bytes"
3913         $OPENFILE -f O_RDWR $DIR/f34e
3914         $CHECKSTAT -s 1000 $DIR/f34e ||
3915                 error "Size of $DIR/f34e not equal to 1000 bytes"
3916 }
3917 run_test 34e "create objects, some with size and some without =="
3918
3919 test_34f() { # bug 6242, 6243
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         SIZE34F=48000
3923         rm -f $DIR/f34f
3924         $MCREATE $DIR/f34f || error "mcreate failed"
3925         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3926         dd if=$DIR/f34f of=$TMP/f34f
3927         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3928         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3929         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3930         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3931         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3932 }
3933 run_test 34f "read from a file with no objects until EOF ======="
3934
3935 test_34g() {
3936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3937
3938         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3939                 error "dd failed"
3940         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3941         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3942                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3943         cancel_lru_locks osc
3944         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3945                 error "wrong size after lock cancel"
3946
3947         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3948         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3949                 error "expanding truncate failed"
3950         cancel_lru_locks osc
3951         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3952                 error "wrong expanded size after lock cancel"
3953 }
3954 run_test 34g "truncate long file ==============================="
3955
3956 test_34h() {
3957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3958
3959         local gid=10
3960         local sz=1000
3961
3962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3963         sync # Flush the cache so that multiop below does not block on cache
3964              # flush when getting the group lock
3965         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3966         MULTIPID=$!
3967
3968         # Since just timed wait is not good enough, let's do a sync write
3969         # that way we are sure enough time for a roundtrip + processing
3970         # passed + 2 seconds of extra margin.
3971         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3972         rm $DIR/${tfile}-1
3973         sleep 2
3974
3975         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3976                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3977                 kill -9 $MULTIPID
3978         fi
3979         wait $MULTIPID
3980         local nsz=`stat -c %s $DIR/$tfile`
3981         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3982 }
3983 run_test 34h "ftruncate file under grouplock should not block"
3984
3985 test_35a() {
3986         cp /bin/sh $DIR/f35a
3987         chmod 444 $DIR/f35a
3988         chown $RUNAS_ID $DIR/f35a
3989         $RUNAS $DIR/f35a && error || true
3990         rm $DIR/f35a
3991 }
3992 run_test 35a "exec file with mode 444 (should return and not leak)"
3993
3994 test_36a() {
3995         rm -f $DIR/f36
3996         utime $DIR/f36 || error "utime failed for MDS"
3997 }
3998 run_test 36a "MDS utime check (mknod, utime)"
3999
4000 test_36b() {
4001         echo "" > $DIR/f36
4002         utime $DIR/f36 || error "utime failed for OST"
4003 }
4004 run_test 36b "OST utime check (open, utime)"
4005
4006 test_36c() {
4007         rm -f $DIR/d36/f36
4008         test_mkdir $DIR/d36
4009         chown $RUNAS_ID $DIR/d36
4010         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4011 }
4012 run_test 36c "non-root MDS utime check (mknod, utime)"
4013
4014 test_36d() {
4015         [ ! -d $DIR/d36 ] && test_36c
4016         echo "" > $DIR/d36/f36
4017         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4018 }
4019 run_test 36d "non-root OST utime check (open, utime)"
4020
4021 test_36e() {
4022         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4023
4024         test_mkdir $DIR/$tdir
4025         touch $DIR/$tdir/$tfile
4026         $RUNAS utime $DIR/$tdir/$tfile &&
4027                 error "utime worked, expected failure" || true
4028 }
4029 run_test 36e "utime on non-owned file (should return error)"
4030
4031 subr_36fh() {
4032         local fl="$1"
4033         local LANG_SAVE=$LANG
4034         local LC_LANG_SAVE=$LC_LANG
4035         export LANG=C LC_LANG=C # for date language
4036
4037         DATESTR="Dec 20  2000"
4038         test_mkdir $DIR/$tdir
4039         lctl set_param fail_loc=$fl
4040         date; date +%s
4041         cp /etc/hosts $DIR/$tdir/$tfile
4042         sync & # write RPC generated with "current" inode timestamp, but delayed
4043         sleep 1
4044         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4045         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4046         cancel_lru_locks $OSC
4047         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4048         date; date +%s
4049         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4050                 echo "BEFORE: $LS_BEFORE" && \
4051                 echo "AFTER : $LS_AFTER" && \
4052                 echo "WANT  : $DATESTR" && \
4053                 error "$DIR/$tdir/$tfile timestamps changed" || true
4054
4055         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4056 }
4057
4058 test_36f() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060
4061         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4062         subr_36fh "0x80000214"
4063 }
4064 run_test 36f "utime on file racing with OST BRW write =========="
4065
4066 test_36g() {
4067         remote_ost_nodsh && skip "remote OST with nodsh"
4068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4069         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4070                 skip "Need MDS version at least 2.12.51"
4071
4072         local fmd_max_age
4073         local fmd
4074         local facet="ost1"
4075         local tgt="obdfilter"
4076
4077         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4078
4079         test_mkdir $DIR/$tdir
4080         fmd_max_age=$(do_facet $facet \
4081                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4082                 head -n 1")
4083
4084         echo "FMD max age: ${fmd_max_age}s"
4085         touch $DIR/$tdir/$tfile
4086         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4087                 gawk '{cnt=cnt+$1}  END{print cnt}')
4088         echo "FMD before: $fmd"
4089         [[ $fmd == 0 ]] &&
4090                 error "FMD wasn't create by touch"
4091         sleep $((fmd_max_age + 12))
4092         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4093                 gawk '{cnt=cnt+$1}  END{print cnt}')
4094         echo "FMD after: $fmd"
4095         [[ $fmd == 0 ]] ||
4096                 error "FMD wasn't expired by ping"
4097 }
4098 run_test 36g "FMD cache expiry ====================="
4099
4100 test_36h() {
4101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4102
4103         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4104         subr_36fh "0x80000227"
4105 }
4106 run_test 36h "utime on file racing with OST BRW write =========="
4107
4108 test_36i() {
4109         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4110
4111         test_mkdir $DIR/$tdir
4112         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4113
4114         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4115         local new_mtime=$((mtime + 200))
4116
4117         #change Modify time of striped dir
4118         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4119                         error "change mtime failed"
4120
4121         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4122
4123         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4124 }
4125 run_test 36i "change mtime on striped directory"
4126
4127 # test_37 - duplicate with tests 32q 32r
4128
4129 test_38() {
4130         local file=$DIR/$tfile
4131         touch $file
4132         openfile -f O_DIRECTORY $file
4133         local RC=$?
4134         local ENOTDIR=20
4135         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4136         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4137 }
4138 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4139
4140 test_39a() { # was test_39
4141         touch $DIR/$tfile
4142         touch $DIR/${tfile}2
4143 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4144 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4145 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4146         sleep 2
4147         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4148         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4149                 echo "mtime"
4150                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4151                 echo "atime"
4152                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4153                 echo "ctime"
4154                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4155                 error "O_TRUNC didn't change timestamps"
4156         fi
4157 }
4158 run_test 39a "mtime changed on create"
4159
4160 test_39b() {
4161         test_mkdir -c1 $DIR/$tdir
4162         cp -p /etc/passwd $DIR/$tdir/fopen
4163         cp -p /etc/passwd $DIR/$tdir/flink
4164         cp -p /etc/passwd $DIR/$tdir/funlink
4165         cp -p /etc/passwd $DIR/$tdir/frename
4166         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4167
4168         sleep 1
4169         echo "aaaaaa" >> $DIR/$tdir/fopen
4170         echo "aaaaaa" >> $DIR/$tdir/flink
4171         echo "aaaaaa" >> $DIR/$tdir/funlink
4172         echo "aaaaaa" >> $DIR/$tdir/frename
4173
4174         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4175         local link_new=`stat -c %Y $DIR/$tdir/flink`
4176         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4177         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4178
4179         cat $DIR/$tdir/fopen > /dev/null
4180         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4181         rm -f $DIR/$tdir/funlink2
4182         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4183
4184         for (( i=0; i < 2; i++ )) ; do
4185                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4186                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4187                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4188                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4189
4190                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4191                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4192                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4193                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4194
4195                 cancel_lru_locks $OSC
4196                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4197         done
4198 }
4199 run_test 39b "mtime change on open, link, unlink, rename  ======"
4200
4201 # this should be set to past
4202 TEST_39_MTIME=`date -d "1 year ago" +%s`
4203
4204 # bug 11063
4205 test_39c() {
4206         touch $DIR1/$tfile
4207         sleep 2
4208         local mtime0=`stat -c %Y $DIR1/$tfile`
4209
4210         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4211         local mtime1=`stat -c %Y $DIR1/$tfile`
4212         [ "$mtime1" = $TEST_39_MTIME ] || \
4213                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4214
4215         local d1=`date +%s`
4216         echo hello >> $DIR1/$tfile
4217         local d2=`date +%s`
4218         local mtime2=`stat -c %Y $DIR1/$tfile`
4219         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4220                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4221
4222         mv $DIR1/$tfile $DIR1/$tfile-1
4223
4224         for (( i=0; i < 2; i++ )) ; do
4225                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4226                 [ "$mtime2" = "$mtime3" ] || \
4227                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4228
4229                 cancel_lru_locks $OSC
4230                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4231         done
4232 }
4233 run_test 39c "mtime change on rename ==========================="
4234
4235 # bug 21114
4236 test_39d() {
4237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4238
4239         touch $DIR1/$tfile
4240         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4241
4242         for (( i=0; i < 2; i++ )) ; do
4243                 local mtime=`stat -c %Y $DIR1/$tfile`
4244                 [ $mtime = $TEST_39_MTIME ] || \
4245                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4246
4247                 cancel_lru_locks $OSC
4248                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4249         done
4250 }
4251 run_test 39d "create, utime, stat =============================="
4252
4253 # bug 21114
4254 test_39e() {
4255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4256
4257         touch $DIR1/$tfile
4258         local mtime1=`stat -c %Y $DIR1/$tfile`
4259
4260         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4261
4262         for (( i=0; i < 2; i++ )) ; do
4263                 local mtime2=`stat -c %Y $DIR1/$tfile`
4264                 [ $mtime2 = $TEST_39_MTIME ] || \
4265                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4266
4267                 cancel_lru_locks $OSC
4268                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4269         done
4270 }
4271 run_test 39e "create, stat, utime, stat ========================"
4272
4273 # bug 21114
4274 test_39f() {
4275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4276
4277         touch $DIR1/$tfile
4278         mtime1=`stat -c %Y $DIR1/$tfile`
4279
4280         sleep 2
4281         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4282
4283         for (( i=0; i < 2; i++ )) ; do
4284                 local mtime2=`stat -c %Y $DIR1/$tfile`
4285                 [ $mtime2 = $TEST_39_MTIME ] || \
4286                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4287
4288                 cancel_lru_locks $OSC
4289                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4290         done
4291 }
4292 run_test 39f "create, stat, sleep, utime, stat ================="
4293
4294 # bug 11063
4295 test_39g() {
4296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4297
4298         echo hello >> $DIR1/$tfile
4299         local mtime1=`stat -c %Y $DIR1/$tfile`
4300
4301         sleep 2
4302         chmod o+r $DIR1/$tfile
4303
4304         for (( i=0; i < 2; i++ )) ; do
4305                 local mtime2=`stat -c %Y $DIR1/$tfile`
4306                 [ "$mtime1" = "$mtime2" ] || \
4307                         error "lost mtime: $mtime2, should be $mtime1"
4308
4309                 cancel_lru_locks $OSC
4310                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4311         done
4312 }
4313 run_test 39g "write, chmod, stat ==============================="
4314
4315 # bug 11063
4316 test_39h() {
4317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4318
4319         touch $DIR1/$tfile
4320         sleep 1
4321
4322         local d1=`date`
4323         echo hello >> $DIR1/$tfile
4324         local mtime1=`stat -c %Y $DIR1/$tfile`
4325
4326         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4327         local d2=`date`
4328         if [ "$d1" != "$d2" ]; then
4329                 echo "write and touch not within one second"
4330         else
4331                 for (( i=0; i < 2; i++ )) ; do
4332                         local mtime2=`stat -c %Y $DIR1/$tfile`
4333                         [ "$mtime2" = $TEST_39_MTIME ] || \
4334                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4335
4336                         cancel_lru_locks $OSC
4337                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4338                 done
4339         fi
4340 }
4341 run_test 39h "write, utime within one second, stat ============="
4342
4343 test_39i() {
4344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4345
4346         touch $DIR1/$tfile
4347         sleep 1
4348
4349         echo hello >> $DIR1/$tfile
4350         local mtime1=`stat -c %Y $DIR1/$tfile`
4351
4352         mv $DIR1/$tfile $DIR1/$tfile-1
4353
4354         for (( i=0; i < 2; i++ )) ; do
4355                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4356
4357                 [ "$mtime1" = "$mtime2" ] || \
4358                         error "lost mtime: $mtime2, should be $mtime1"
4359
4360                 cancel_lru_locks $OSC
4361                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4362         done
4363 }
4364 run_test 39i "write, rename, stat =============================="
4365
4366 test_39j() {
4367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4368
4369         start_full_debug_logging
4370         touch $DIR1/$tfile
4371         sleep 1
4372
4373         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4374         lctl set_param fail_loc=0x80000412
4375         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4376                 error "multiop failed"
4377         local multipid=$!
4378         local mtime1=`stat -c %Y $DIR1/$tfile`
4379
4380         mv $DIR1/$tfile $DIR1/$tfile-1
4381
4382         kill -USR1 $multipid
4383         wait $multipid || error "multiop close failed"
4384
4385         for (( i=0; i < 2; i++ )) ; do
4386                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4387                 [ "$mtime1" = "$mtime2" ] ||
4388                         error "mtime is lost on close: $mtime2, " \
4389                               "should be $mtime1"
4390
4391                 cancel_lru_locks
4392                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4393         done
4394         lctl set_param fail_loc=0
4395         stop_full_debug_logging
4396 }
4397 run_test 39j "write, rename, close, stat ======================="
4398
4399 test_39k() {
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401
4402         touch $DIR1/$tfile
4403         sleep 1
4404
4405         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4406         local multipid=$!
4407         local mtime1=`stat -c %Y $DIR1/$tfile`
4408
4409         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4410
4411         kill -USR1 $multipid
4412         wait $multipid || error "multiop close failed"
4413
4414         for (( i=0; i < 2; i++ )) ; do
4415                 local mtime2=`stat -c %Y $DIR1/$tfile`
4416
4417                 [ "$mtime2" = $TEST_39_MTIME ] || \
4418                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4419
4420                 cancel_lru_locks
4421                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4422         done
4423 }
4424 run_test 39k "write, utime, close, stat ========================"
4425
4426 # this should be set to future
4427 TEST_39_ATIME=`date -d "1 year" +%s`
4428
4429 test_39l() {
4430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4431         remote_mds_nodsh && skip "remote MDS with nodsh"
4432
4433         local atime_diff=$(do_facet $SINGLEMDS \
4434                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4435         rm -rf $DIR/$tdir
4436         mkdir -p $DIR/$tdir
4437
4438         # test setting directory atime to future
4439         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4440         local atime=$(stat -c %X $DIR/$tdir)
4441         [ "$atime" = $TEST_39_ATIME ] ||
4442                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4443
4444         # test setting directory atime from future to now
4445         local now=$(date +%s)
4446         touch -a -d @$now $DIR/$tdir
4447
4448         atime=$(stat -c %X $DIR/$tdir)
4449         [ "$atime" -eq "$now"  ] ||
4450                 error "atime is not updated from future: $atime, $now"
4451
4452         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4453         sleep 3
4454
4455         # test setting directory atime when now > dir atime + atime_diff
4456         local d1=$(date +%s)
4457         ls $DIR/$tdir
4458         local d2=$(date +%s)
4459         cancel_lru_locks mdc
4460         atime=$(stat -c %X $DIR/$tdir)
4461         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4462                 error "atime is not updated  : $atime, should be $d2"
4463
4464         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4465         sleep 3
4466
4467         # test not setting directory atime when now < dir atime + atime_diff
4468         ls $DIR/$tdir
4469         cancel_lru_locks mdc
4470         atime=$(stat -c %X $DIR/$tdir)
4471         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4472                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4473
4474         do_facet $SINGLEMDS \
4475                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4476 }
4477 run_test 39l "directory atime update ==========================="
4478
4479 test_39m() {
4480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4481
4482         touch $DIR1/$tfile
4483         sleep 2
4484         local far_past_mtime=$(date -d "May 29 1953" +%s)
4485         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4486
4487         touch -m -d @$far_past_mtime $DIR1/$tfile
4488         touch -a -d @$far_past_atime $DIR1/$tfile
4489
4490         for (( i=0; i < 2; i++ )) ; do
4491                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4492                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4493                         error "atime or mtime set incorrectly"
4494
4495                 cancel_lru_locks $OSC
4496                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4497         done
4498 }
4499 run_test 39m "test atime and mtime before 1970"
4500
4501 test_39n() { # LU-3832
4502         remote_mds_nodsh && skip "remote MDS with nodsh"
4503
4504         local atime_diff=$(do_facet $SINGLEMDS \
4505                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4506         local atime0
4507         local atime1
4508         local atime2
4509
4510         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4511
4512         rm -rf $DIR/$tfile
4513         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4514         atime0=$(stat -c %X $DIR/$tfile)
4515
4516         sleep 5
4517         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4518         atime1=$(stat -c %X $DIR/$tfile)
4519
4520         sleep 5
4521         cancel_lru_locks mdc
4522         cancel_lru_locks osc
4523         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4524         atime2=$(stat -c %X $DIR/$tfile)
4525
4526         do_facet $SINGLEMDS \
4527                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4528
4529         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4530         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4531 }
4532 run_test 39n "check that O_NOATIME is honored"
4533
4534 test_39o() {
4535         TESTDIR=$DIR/$tdir/$tfile
4536         [ -e $TESTDIR ] && rm -rf $TESTDIR
4537         mkdir -p $TESTDIR
4538         cd $TESTDIR
4539         links1=2
4540         ls
4541         mkdir a b
4542         ls
4543         links2=$(stat -c %h .)
4544         [ $(($links1 + 2)) != $links2 ] &&
4545                 error "wrong links count $(($links1 + 2)) != $links2"
4546         rmdir b
4547         links3=$(stat -c %h .)
4548         [ $(($links1 + 1)) != $links3 ] &&
4549                 error "wrong links count $links1 != $links3"
4550         return 0
4551 }
4552 run_test 39o "directory cached attributes updated after create"
4553
4554 test_39p() {
4555         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4556
4557         local MDTIDX=1
4558         TESTDIR=$DIR/$tdir/$tdir
4559         [ -e $TESTDIR ] && rm -rf $TESTDIR
4560         test_mkdir -p $TESTDIR
4561         cd $TESTDIR
4562         links1=2
4563         ls
4564         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4565         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4566         ls
4567         links2=$(stat -c %h .)
4568         [ $(($links1 + 2)) != $links2 ] &&
4569                 error "wrong links count $(($links1 + 2)) != $links2"
4570         rmdir remote_dir2
4571         links3=$(stat -c %h .)
4572         [ $(($links1 + 1)) != $links3 ] &&
4573                 error "wrong links count $links1 != $links3"
4574         return 0
4575 }
4576 run_test 39p "remote directory cached attributes updated after create ========"
4577
4578 test_39r() {
4579         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4580                 skip "no atime update on old OST"
4581         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4582                 skip_env "ldiskfs only test"
4583         fi
4584
4585         local saved_adiff
4586         saved_adiff=$(do_facet ost1 \
4587                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4588         stack_trap "do_facet ost1 \
4589                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4590
4591         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4592
4593         $LFS setstripe -i 0 $DIR/$tfile
4594         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4595                 error "can't write initial file"
4596         cancel_lru_locks osc
4597
4598         # exceed atime_diff and access file
4599         sleep 6
4600         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4601
4602         local atime_cli=$(stat -c %X $DIR/$tfile)
4603         echo "client atime: $atime_cli"
4604         # allow atime update to be written to device
4605         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4606         sleep 5
4607
4608         local ostdev=$(ostdevname 1)
4609         local fid=($(lfs getstripe -y $DIR/$tfile |
4610                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4611         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4612         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4613
4614         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4615         local atime_ost=$(do_facet ost1 "$cmd" |&
4616                           awk -F'[: ]' '/atime:/ { print $4 }')
4617         (( atime_cli == atime_ost )) ||
4618                 error "atime on client $atime_cli != ost $atime_ost"
4619 }
4620 run_test 39r "lazy atime update on OST"
4621
4622 test_39q() { # LU-8041
4623         local testdir=$DIR/$tdir
4624         mkdir -p $testdir
4625         multiop_bg_pause $testdir D_c || error "multiop failed"
4626         local multipid=$!
4627         cancel_lru_locks mdc
4628         kill -USR1 $multipid
4629         local atime=$(stat -c %X $testdir)
4630         [ "$atime" -ne 0 ] || error "atime is zero"
4631 }
4632 run_test 39q "close won't zero out atime"
4633
4634 test_40() {
4635         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4636         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4637                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4638         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4639                 error "$tfile is not 4096 bytes in size"
4640 }
4641 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4642
4643 test_41() {
4644         # bug 1553
4645         small_write $DIR/f41 18
4646 }
4647 run_test 41 "test small file write + fstat ====================="
4648
4649 count_ost_writes() {
4650         lctl get_param -n ${OSC}.*.stats |
4651                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4652                         END { printf("%0.0f", writes) }'
4653 }
4654
4655 # decent default
4656 WRITEBACK_SAVE=500
4657 DIRTY_RATIO_SAVE=40
4658 MAX_DIRTY_RATIO=50
4659 BG_DIRTY_RATIO_SAVE=10
4660 MAX_BG_DIRTY_RATIO=25
4661
4662 start_writeback() {
4663         trap 0
4664         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4665         # dirty_ratio, dirty_background_ratio
4666         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4667                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4668                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4669                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4670         else
4671                 # if file not here, we are a 2.4 kernel
4672                 kill -CONT `pidof kupdated`
4673         fi
4674 }
4675
4676 stop_writeback() {
4677         # setup the trap first, so someone cannot exit the test at the
4678         # exact wrong time and mess up a machine
4679         trap start_writeback EXIT
4680         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4681         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4682                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4683                 sysctl -w vm.dirty_writeback_centisecs=0
4684                 sysctl -w vm.dirty_writeback_centisecs=0
4685                 # save and increase /proc/sys/vm/dirty_ratio
4686                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4687                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4688                 # save and increase /proc/sys/vm/dirty_background_ratio
4689                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4690                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4691         else
4692                 # if file not here, we are a 2.4 kernel
4693                 kill -STOP `pidof kupdated`
4694         fi
4695 }
4696
4697 # ensure that all stripes have some grant before we test client-side cache
4698 setup_test42() {
4699         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4700                 dd if=/dev/zero of=$i bs=4k count=1
4701                 rm $i
4702         done
4703 }
4704
4705 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4706 # file truncation, and file removal.
4707 test_42a() {
4708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4709
4710         setup_test42
4711         cancel_lru_locks $OSC
4712         stop_writeback
4713         sync; sleep 1; sync # just to be safe
4714         BEFOREWRITES=`count_ost_writes`
4715         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4716         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4717         AFTERWRITES=`count_ost_writes`
4718         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4719                 error "$BEFOREWRITES < $AFTERWRITES"
4720         start_writeback
4721 }
4722 run_test 42a "ensure that we don't flush on close"
4723
4724 test_42b() {
4725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4726
4727         setup_test42
4728         cancel_lru_locks $OSC
4729         stop_writeback
4730         sync
4731         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4732         BEFOREWRITES=$(count_ost_writes)
4733         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4734         AFTERWRITES=$(count_ost_writes)
4735         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4736                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4737         fi
4738         BEFOREWRITES=$(count_ost_writes)
4739         sync || error "sync: $?"
4740         AFTERWRITES=$(count_ost_writes)
4741         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4742                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4743         fi
4744         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4745         start_writeback
4746         return 0
4747 }
4748 run_test 42b "test destroy of file with cached dirty data ======"
4749
4750 # if these tests just want to test the effect of truncation,
4751 # they have to be very careful.  consider:
4752 # - the first open gets a {0,EOF}PR lock
4753 # - the first write conflicts and gets a {0, count-1}PW
4754 # - the rest of the writes are under {count,EOF}PW
4755 # - the open for truncate tries to match a {0,EOF}PR
4756 #   for the filesize and cancels the PWs.
4757 # any number of fixes (don't get {0,EOF} on open, match
4758 # composite locks, do smarter file size management) fix
4759 # this, but for now we want these tests to verify that
4760 # the cancellation with truncate intent works, so we
4761 # start the file with a full-file pw lock to match against
4762 # until the truncate.
4763 trunc_test() {
4764         test=$1
4765         file=$DIR/$test
4766         offset=$2
4767         cancel_lru_locks $OSC
4768         stop_writeback
4769         # prime the file with 0,EOF PW to match
4770         touch $file
4771         $TRUNCATE $file 0
4772         sync; sync
4773         # now the real test..
4774         dd if=/dev/zero of=$file bs=1024 count=100
4775         BEFOREWRITES=`count_ost_writes`
4776         $TRUNCATE $file $offset
4777         cancel_lru_locks $OSC
4778         AFTERWRITES=`count_ost_writes`
4779         start_writeback
4780 }
4781
4782 test_42c() {
4783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4784
4785         trunc_test 42c 1024
4786         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4787                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4788         rm $file
4789 }
4790 run_test 42c "test partial truncate of file with cached dirty data"
4791
4792 test_42d() {
4793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4794
4795         trunc_test 42d 0
4796         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4797                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4798         rm $file
4799 }
4800 run_test 42d "test complete truncate of file with cached dirty data"
4801
4802 test_42e() { # bug22074
4803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4804
4805         local TDIR=$DIR/${tdir}e
4806         local pages=16 # hardcoded 16 pages, don't change it.
4807         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4808         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4809         local max_dirty_mb
4810         local warmup_files
4811
4812         test_mkdir $DIR/${tdir}e
4813         $LFS setstripe -c 1 $TDIR
4814         createmany -o $TDIR/f $files
4815
4816         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4817
4818         # we assume that with $OSTCOUNT files, at least one of them will
4819         # be allocated on OST0.
4820         warmup_files=$((OSTCOUNT * max_dirty_mb))
4821         createmany -o $TDIR/w $warmup_files
4822
4823         # write a large amount of data into one file and sync, to get good
4824         # avail_grant number from OST.
4825         for ((i=0; i<$warmup_files; i++)); do
4826                 idx=$($LFS getstripe -i $TDIR/w$i)
4827                 [ $idx -ne 0 ] && continue
4828                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4829                 break
4830         done
4831         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4832         sync
4833         $LCTL get_param $proc_osc0/cur_dirty_bytes
4834         $LCTL get_param $proc_osc0/cur_grant_bytes
4835
4836         # create as much dirty pages as we can while not to trigger the actual
4837         # RPCs directly. but depends on the env, VFS may trigger flush during this
4838         # period, hopefully we are good.
4839         for ((i=0; i<$warmup_files; i++)); do
4840                 idx=$($LFS getstripe -i $TDIR/w$i)
4841                 [ $idx -ne 0 ] && continue
4842                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4843         done
4844         $LCTL get_param $proc_osc0/cur_dirty_bytes
4845         $LCTL get_param $proc_osc0/cur_grant_bytes
4846
4847         # perform the real test
4848         $LCTL set_param $proc_osc0/rpc_stats 0
4849         for ((;i<$files; i++)); do
4850                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4851                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4852         done
4853         sync
4854         $LCTL get_param $proc_osc0/rpc_stats
4855
4856         local percent=0
4857         local have_ppr=false
4858         $LCTL get_param $proc_osc0/rpc_stats |
4859                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4860                         # skip lines until we are at the RPC histogram data
4861                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4862                         $have_ppr || continue
4863
4864                         # we only want the percent stat for < 16 pages
4865                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4866
4867                         percent=$((percent + WPCT))
4868                         if [[ $percent -gt 15 ]]; then
4869                                 error "less than 16-pages write RPCs" \
4870                                       "$percent% > 15%"
4871                                 break
4872                         fi
4873                 done
4874         rm -rf $TDIR
4875 }
4876 run_test 42e "verify sub-RPC writes are not done synchronously"
4877
4878 test_43A() { # was test_43
4879         test_mkdir $DIR/$tdir
4880         cp -p /bin/ls $DIR/$tdir/$tfile
4881         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4882         pid=$!
4883         # give multiop a chance to open
4884         sleep 1
4885
4886         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4887         kill -USR1 $pid
4888         # Wait for multiop to exit
4889         wait $pid
4890 }
4891 run_test 43A "execution of file opened for write should return -ETXTBSY"
4892
4893 test_43a() {
4894         test_mkdir $DIR/$tdir
4895         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4896         $DIR/$tdir/sleep 60 &
4897         SLEEP_PID=$!
4898         # Make sure exec of $tdir/sleep wins race with truncate
4899         sleep 1
4900         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4901         kill $SLEEP_PID
4902 }
4903 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4904
4905 test_43b() {
4906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4907
4908         test_mkdir $DIR/$tdir
4909         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4910         $DIR/$tdir/sleep 60 &
4911         SLEEP_PID=$!
4912         # Make sure exec of $tdir/sleep wins race with truncate
4913         sleep 1
4914         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4915         kill $SLEEP_PID
4916 }
4917 run_test 43b "truncate of file being executed should return -ETXTBSY"
4918
4919 test_43c() {
4920         local testdir="$DIR/$tdir"
4921         test_mkdir $testdir
4922         cp $SHELL $testdir/
4923         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4924                 ( cd $testdir && md5sum -c )
4925 }
4926 run_test 43c "md5sum of copy into lustre"
4927
4928 test_44A() { # was test_44
4929         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4930
4931         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4932         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4933 }
4934 run_test 44A "zero length read from a sparse stripe"
4935
4936 test_44a() {
4937         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4938                 awk '{ print $2 }')
4939         [ -z "$nstripe" ] && skip "can't get stripe info"
4940         [[ $nstripe -gt $OSTCOUNT ]] &&
4941                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4942
4943         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4944                 awk '{ print $2 }')
4945         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4946                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4947                         awk '{ print $2 }')
4948         fi
4949
4950         OFFSETS="0 $((stride/2)) $((stride-1))"
4951         for offset in $OFFSETS; do
4952                 for i in $(seq 0 $((nstripe-1))); do
4953                         local GLOBALOFFSETS=""
4954                         # size in Bytes
4955                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4956                         local myfn=$DIR/d44a-$size
4957                         echo "--------writing $myfn at $size"
4958                         ll_sparseness_write $myfn $size ||
4959                                 error "ll_sparseness_write"
4960                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4961                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4962                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4963
4964                         for j in $(seq 0 $((nstripe-1))); do
4965                                 # size in Bytes
4966                                 size=$((((j + $nstripe )*$stride + $offset)))
4967                                 ll_sparseness_write $myfn $size ||
4968                                         error "ll_sparseness_write"
4969                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4970                         done
4971                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4972                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4973                         rm -f $myfn
4974                 done
4975         done
4976 }
4977 run_test 44a "test sparse pwrite ==============================="
4978
4979 dirty_osc_total() {
4980         tot=0
4981         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4982                 tot=$(($tot + $d))
4983         done
4984         echo $tot
4985 }
4986 do_dirty_record() {
4987         before=`dirty_osc_total`
4988         echo executing "\"$*\""
4989         eval $*
4990         after=`dirty_osc_total`
4991         echo before $before, after $after
4992 }
4993 test_45() {
4994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4995
4996         f="$DIR/f45"
4997         # Obtain grants from OST if it supports it
4998         echo blah > ${f}_grant
4999         stop_writeback
5000         sync
5001         do_dirty_record "echo blah > $f"
5002         [[ $before -eq $after ]] && error "write wasn't cached"
5003         do_dirty_record "> $f"
5004         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5005         do_dirty_record "echo blah > $f"
5006         [[ $before -eq $after ]] && error "write wasn't cached"
5007         do_dirty_record "sync"
5008         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5009         do_dirty_record "echo blah > $f"
5010         [[ $before -eq $after ]] && error "write wasn't cached"
5011         do_dirty_record "cancel_lru_locks osc"
5012         [[ $before -gt $after ]] ||
5013                 error "lock cancellation didn't lower dirty count"
5014         start_writeback
5015 }
5016 run_test 45 "osc io page accounting ============================"
5017
5018 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5019 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5020 # objects offset and an assert hit when an rpc was built with 1023's mapped
5021 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5022 test_46() {
5023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5024
5025         f="$DIR/f46"
5026         stop_writeback
5027         sync
5028         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5029         sync
5030         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5031         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5032         sync
5033         start_writeback
5034 }
5035 run_test 46 "dirtying a previously written page ================"
5036
5037 # test_47 is removed "Device nodes check" is moved to test_28
5038
5039 test_48a() { # bug 2399
5040         [ "$mds1_FSTYPE" = "zfs" ] &&
5041         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5042                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5043
5044         test_mkdir $DIR/$tdir
5045         cd $DIR/$tdir
5046         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5047         test_mkdir $DIR/$tdir
5048         touch foo || error "'touch foo' failed after recreating cwd"
5049         test_mkdir bar
5050         touch .foo || error "'touch .foo' failed after recreating cwd"
5051         test_mkdir .bar
5052         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5053         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5054         cd . || error "'cd .' failed after recreating cwd"
5055         mkdir . && error "'mkdir .' worked after recreating cwd"
5056         rmdir . && error "'rmdir .' worked after recreating cwd"
5057         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5058         cd .. || error "'cd ..' failed after recreating cwd"
5059 }
5060 run_test 48a "Access renamed working dir (should return errors)="
5061
5062 test_48b() { # bug 2399
5063         rm -rf $DIR/$tdir
5064         test_mkdir $DIR/$tdir
5065         cd $DIR/$tdir
5066         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5067         touch foo && error "'touch foo' worked after removing cwd"
5068         mkdir foo && error "'mkdir foo' worked after removing cwd"
5069         touch .foo && error "'touch .foo' worked after removing cwd"
5070         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5071         ls . > /dev/null && error "'ls .' worked after removing cwd"
5072         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5073         mkdir . && error "'mkdir .' worked after removing cwd"
5074         rmdir . && error "'rmdir .' worked after removing cwd"
5075         ln -s . foo && error "'ln -s .' worked after removing cwd"
5076         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5077 }
5078 run_test 48b "Access removed working dir (should return errors)="
5079
5080 test_48c() { # bug 2350
5081         #lctl set_param debug=-1
5082         #set -vx
5083         rm -rf $DIR/$tdir
5084         test_mkdir -p $DIR/$tdir/dir
5085         cd $DIR/$tdir/dir
5086         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5087         $TRACE touch foo && error "touch foo worked after removing cwd"
5088         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5089         touch .foo && error "touch .foo worked after removing cwd"
5090         mkdir .foo && error "mkdir .foo worked after removing cwd"
5091         $TRACE ls . && error "'ls .' worked after removing cwd"
5092         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5093         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5094         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5095         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5096         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5097 }
5098 run_test 48c "Access removed working subdir (should return errors)"
5099
5100 test_48d() { # bug 2350
5101         #lctl set_param debug=-1
5102         #set -vx
5103         rm -rf $DIR/$tdir
5104         test_mkdir -p $DIR/$tdir/dir
5105         cd $DIR/$tdir/dir
5106         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5107         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5108         $TRACE touch foo && error "'touch foo' worked after removing parent"
5109         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5110         touch .foo && error "'touch .foo' worked after removing parent"
5111         mkdir .foo && error "mkdir .foo worked after removing parent"
5112         $TRACE ls . && error "'ls .' worked after removing parent"
5113         $TRACE ls .. && error "'ls ..' worked after removing parent"
5114         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5115         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5116         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5117         true
5118 }
5119 run_test 48d "Access removed parent subdir (should return errors)"
5120
5121 test_48e() { # bug 4134
5122         #lctl set_param debug=-1
5123         #set -vx
5124         rm -rf $DIR/$tdir
5125         test_mkdir -p $DIR/$tdir/dir
5126         cd $DIR/$tdir/dir
5127         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5128         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5129         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5130         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5131         # On a buggy kernel addition of "touch foo" after cd .. will
5132         # produce kernel oops in lookup_hash_it
5133         touch ../foo && error "'cd ..' worked after recreate parent"
5134         cd $DIR
5135         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5136 }
5137 run_test 48e "Access to recreated parent subdir (should return errors)"
5138
5139 test_48f() {
5140         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5141                 skip "need MDS >= 2.13.55"
5142         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5143         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5144                 skip "needs different host for mdt1 mdt2"
5145         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5146
5147         $LFS mkdir -i0 $DIR/$tdir
5148         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5149
5150         for d in sub1 sub2 sub3; do
5151                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5152                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5153                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5154         done
5155
5156         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5157 }
5158 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5159
5160 test_49() { # LU-1030
5161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5162         remote_ost_nodsh && skip "remote OST with nodsh"
5163
5164         # get ost1 size - $FSNAME-OST0000
5165         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5166                 awk '{ print $4 }')
5167         # write 800M at maximum
5168         [[ $ost1_size -lt 2 ]] && ost1_size=2
5169         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5170
5171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5172         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5173         local dd_pid=$!
5174
5175         # change max_pages_per_rpc while writing the file
5176         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5177         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5178         # loop until dd process exits
5179         while ps ax -opid | grep -wq $dd_pid; do
5180                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5181                 sleep $((RANDOM % 5 + 1))
5182         done
5183         # restore original max_pages_per_rpc
5184         $LCTL set_param $osc1_mppc=$orig_mppc
5185         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5186 }
5187 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5188
5189 test_50() {
5190         # bug 1485
5191         test_mkdir $DIR/$tdir
5192         cd $DIR/$tdir
5193         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5194 }
5195 run_test 50 "special situations: /proc symlinks  ==============="
5196
5197 test_51a() {    # was test_51
5198         # bug 1516 - create an empty entry right after ".." then split dir
5199         test_mkdir -c1 $DIR/$tdir
5200         touch $DIR/$tdir/foo
5201         $MCREATE $DIR/$tdir/bar
5202         rm $DIR/$tdir/foo
5203         createmany -m $DIR/$tdir/longfile 201
5204         FNUM=202
5205         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5206                 $MCREATE $DIR/$tdir/longfile$FNUM
5207                 FNUM=$(($FNUM + 1))
5208                 echo -n "+"
5209         done
5210         echo
5211         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5212 }
5213 run_test 51a "special situations: split htree with empty entry =="
5214
5215 cleanup_print_lfs_df () {
5216         trap 0
5217         $LFS df
5218         $LFS df -i
5219 }
5220
5221 test_51b() {
5222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5223
5224         local dir=$DIR/$tdir
5225         local nrdirs=$((65536 + 100))
5226
5227         # cleanup the directory
5228         rm -fr $dir
5229
5230         test_mkdir -c1 $dir
5231
5232         $LFS df
5233         $LFS df -i
5234         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5235         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5236         [[ $numfree -lt $nrdirs ]] &&
5237                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5238
5239         # need to check free space for the directories as well
5240         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5241         numfree=$(( blkfree / $(fs_inode_ksize) ))
5242         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5243
5244         trap cleanup_print_lfs_df EXIT
5245
5246         # create files
5247         createmany -d $dir/d $nrdirs || {
5248                 unlinkmany $dir/d $nrdirs
5249                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5250         }
5251
5252         # really created :
5253         nrdirs=$(ls -U $dir | wc -l)
5254
5255         # unlink all but 100 subdirectories, then check it still works
5256         local left=100
5257         local delete=$((nrdirs - left))
5258
5259         $LFS df
5260         $LFS df -i
5261
5262         # for ldiskfs the nlink count should be 1, but this is OSD specific
5263         # and so this is listed for informational purposes only
5264         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5265         unlinkmany -d $dir/d $delete ||
5266                 error "unlink of first $delete subdirs failed"
5267
5268         echo "nlink between: $(stat -c %h $dir)"
5269         local found=$(ls -U $dir | wc -l)
5270         [ $found -ne $left ] &&
5271                 error "can't find subdirs: found only $found, expected $left"
5272
5273         unlinkmany -d $dir/d $delete $left ||
5274                 error "unlink of second $left subdirs failed"
5275         # regardless of whether the backing filesystem tracks nlink accurately
5276         # or not, the nlink count shouldn't be more than "." and ".." here
5277         local after=$(stat -c %h $dir)
5278         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5279                 echo "nlink after: $after"
5280
5281         cleanup_print_lfs_df
5282 }
5283 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5284
5285 test_51d() {
5286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5287         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5288
5289         test_mkdir $DIR/$tdir
5290         createmany -o $DIR/$tdir/t- 1000
5291         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5292         for N in $(seq 0 $((OSTCOUNT - 1))); do
5293                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5294                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5295                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5296                         '($1 == '$N') { objs += 1 } \
5297                         END { printf("%0.0f", objs) }')
5298                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5299         done
5300         unlinkmany $DIR/$tdir/t- 1000
5301
5302         NLAST=0
5303         for N in $(seq 1 $((OSTCOUNT - 1))); do
5304                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5305                         error "OST $N has less objects vs OST $NLAST" \
5306                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5307                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5308                         error "OST $N has less objects vs OST $NLAST" \
5309                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5310
5311                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5312                         error "OST $N has less #0 objects vs OST $NLAST" \
5313                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5314                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5315                         error "OST $N has less #0 objects vs OST $NLAST" \
5316                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5317                 NLAST=$N
5318         done
5319         rm -f $TMP/$tfile
5320 }
5321 run_test 51d "check object distribution"
5322
5323 test_51e() {
5324         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5325                 skip_env "ldiskfs only test"
5326         fi
5327
5328         test_mkdir -c1 $DIR/$tdir
5329         test_mkdir -c1 $DIR/$tdir/d0
5330
5331         touch $DIR/$tdir/d0/foo
5332         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5333                 error "file exceed 65000 nlink limit!"
5334         unlinkmany $DIR/$tdir/d0/f- 65001
5335         return 0
5336 }
5337 run_test 51e "check file nlink limit"
5338
5339 test_51f() {
5340         test_mkdir $DIR/$tdir
5341
5342         local max=100000
5343         local ulimit_old=$(ulimit -n)
5344         local spare=20 # number of spare fd's for scripts/libraries, etc.
5345         local mdt=$($LFS getstripe -m $DIR/$tdir)
5346         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5347
5348         echo "MDT$mdt numfree=$numfree, max=$max"
5349         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5350         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5351                 while ! ulimit -n $((numfree + spare)); do
5352                         numfree=$((numfree * 3 / 4))
5353                 done
5354                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5355         else
5356                 echo "left ulimit at $ulimit_old"
5357         fi
5358
5359         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5360                 unlinkmany $DIR/$tdir/f $numfree
5361                 error "create+open $numfree files in $DIR/$tdir failed"
5362         }
5363         ulimit -n $ulimit_old
5364
5365         # if createmany exits at 120s there will be fewer than $numfree files
5366         unlinkmany $DIR/$tdir/f $numfree || true
5367 }
5368 run_test 51f "check many open files limit"
5369
5370 test_52a() {
5371         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5372         test_mkdir $DIR/$tdir
5373         touch $DIR/$tdir/foo
5374         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5375         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5376         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5377         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5378         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5379                                         error "link worked"
5380         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5381         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5382         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5383                                                      error "lsattr"
5384         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5385         cp -r $DIR/$tdir $TMP/
5386         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5387 }
5388 run_test 52a "append-only flag test (should return errors)"
5389
5390 test_52b() {
5391         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5392         test_mkdir $DIR/$tdir
5393         touch $DIR/$tdir/foo
5394         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5395         cat test > $DIR/$tdir/foo && error "cat test worked"
5396         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5397         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5398         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5399                                         error "link worked"
5400         echo foo >> $DIR/$tdir/foo && error "echo worked"
5401         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5402         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5403         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5404         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5405                                                         error "lsattr"
5406         chattr -i $DIR/$tdir/foo || error "chattr failed"
5407
5408         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5409 }
5410 run_test 52b "immutable flag test (should return errors) ======="
5411
5412 test_53() {
5413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5414         remote_mds_nodsh && skip "remote MDS with nodsh"
5415         remote_ost_nodsh && skip "remote OST with nodsh"
5416
5417         local param
5418         local param_seq
5419         local ostname
5420         local mds_last
5421         local mds_last_seq
5422         local ost_last
5423         local ost_last_seq
5424         local ost_last_id
5425         local ostnum
5426         local node
5427         local found=false
5428         local support_last_seq=true
5429
5430         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5431                 support_last_seq=false
5432
5433         # only test MDT0000
5434         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5435         local value
5436         for value in $(do_facet $SINGLEMDS \
5437                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5438                 param=$(echo ${value[0]} | cut -d "=" -f1)
5439                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5440
5441                 if $support_last_seq; then
5442                         param_seq=$(echo $param |
5443                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5444                         mds_last_seq=$(do_facet $SINGLEMDS \
5445                                        $LCTL get_param -n $param_seq)
5446                 fi
5447                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5448
5449                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5450                 node=$(facet_active_host ost$((ostnum+1)))
5451                 param="obdfilter.$ostname.last_id"
5452                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5453                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5454                         ost_last_id=$ost_last
5455
5456                         if $support_last_seq; then
5457                                 ost_last_id=$(echo $ost_last |
5458                                               awk -F':' '{print $2}' |
5459                                               sed -e "s/^0x//g")
5460                                 ost_last_seq=$(echo $ost_last |
5461                                                awk -F':' '{print $1}')
5462                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5463                         fi
5464
5465                         if [[ $ost_last_id != $mds_last ]]; then
5466                                 error "$ost_last_id != $mds_last"
5467                         else
5468                                 found=true
5469                                 break
5470                         fi
5471                 done
5472         done
5473         $found || error "can not match last_seq/last_id for $mdtosc"
5474         return 0
5475 }
5476 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5477
5478 test_54a() {
5479         perl -MSocket -e ';' || skip "no Socket perl module installed"
5480
5481         $SOCKETSERVER $DIR/socket ||
5482                 error "$SOCKETSERVER $DIR/socket failed: $?"
5483         $SOCKETCLIENT $DIR/socket ||
5484                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5485         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5486 }
5487 run_test 54a "unix domain socket test =========================="
5488
5489 test_54b() {
5490         f="$DIR/f54b"
5491         mknod $f c 1 3
5492         chmod 0666 $f
5493         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5494 }
5495 run_test 54b "char device works in lustre ======================"
5496
5497 find_loop_dev() {
5498         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5499         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5500         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5501
5502         for i in $(seq 3 7); do
5503                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5504                 LOOPDEV=$LOOPBASE$i
5505                 LOOPNUM=$i
5506                 break
5507         done
5508 }
5509
5510 cleanup_54c() {
5511         local rc=0
5512         loopdev="$DIR/loop54c"
5513
5514         trap 0
5515         $UMOUNT $DIR/$tdir || rc=$?
5516         losetup -d $loopdev || true
5517         losetup -d $LOOPDEV || true
5518         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5519         return $rc
5520 }
5521
5522 test_54c() {
5523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5524
5525         loopdev="$DIR/loop54c"
5526
5527         find_loop_dev
5528         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5529         trap cleanup_54c EXIT
5530         mknod $loopdev b 7 $LOOPNUM
5531         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5532         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5533         losetup $loopdev $DIR/$tfile ||
5534                 error "can't set up $loopdev for $DIR/$tfile"
5535         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5536         test_mkdir $DIR/$tdir
5537         mount -t ext2 $loopdev $DIR/$tdir ||
5538                 error "error mounting $loopdev on $DIR/$tdir"
5539         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5540                 error "dd write"
5541         df $DIR/$tdir
5542         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5543                 error "dd read"
5544         cleanup_54c
5545 }
5546 run_test 54c "block device works in lustre ====================="
5547
5548 test_54d() {
5549         f="$DIR/f54d"
5550         string="aaaaaa"
5551         mknod $f p
5552         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5553 }
5554 run_test 54d "fifo device works in lustre ======================"
5555
5556 test_54e() {
5557         f="$DIR/f54e"
5558         string="aaaaaa"
5559         cp -aL /dev/console $f
5560         echo $string > $f || error "echo $string to $f failed"
5561 }
5562 run_test 54e "console/tty device works in lustre ======================"
5563
5564 test_56a() {
5565         local numfiles=3
5566         local dir=$DIR/$tdir
5567
5568         rm -rf $dir
5569         test_mkdir -p $dir/dir
5570         for i in $(seq $numfiles); do
5571                 touch $dir/file$i
5572                 touch $dir/dir/file$i
5573         done
5574
5575         local numcomp=$($LFS getstripe --component-count $dir)
5576
5577         [[ $numcomp == 0 ]] && numcomp=1
5578
5579         # test lfs getstripe with --recursive
5580         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5581
5582         [[ $filenum -eq $((numfiles * 2)) ]] ||
5583                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5584         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5585         [[ $filenum -eq $numfiles ]] ||
5586                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5587         echo "$LFS getstripe showed obdidx or l_ost_idx"
5588
5589         # test lfs getstripe with file instead of dir
5590         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5591         [[ $filenum -eq 1 ]] ||
5592                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5593         echo "$LFS getstripe file1 passed"
5594
5595         #test lfs getstripe with --verbose
5596         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5597         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5598                 error "$LFS getstripe --verbose $dir: "\
5599                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5600         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5601                 error "$LFS getstripe $dir: showed lmm_magic"
5602
5603         #test lfs getstripe with -v prints lmm_fid
5604         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5605         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5606                 error "$LFS getstripe -v $dir: "\
5607                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5608         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5609                 error "$LFS getstripe $dir: showed lmm_fid by default"
5610         echo "$LFS getstripe --verbose passed"
5611
5612         #check for FID information
5613         local fid1=$($LFS getstripe --fid $dir/file1)
5614         local fid2=$($LFS getstripe --verbose $dir/file1 |
5615                      awk '/lmm_fid: / { print $2; exit; }')
5616         local fid3=$($LFS path2fid $dir/file1)
5617
5618         [ "$fid1" != "$fid2" ] &&
5619                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5620         [ "$fid1" != "$fid3" ] &&
5621                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5622         echo "$LFS getstripe --fid passed"
5623
5624         #test lfs getstripe with --obd
5625         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5626                 error "$LFS getstripe --obd wrong_uuid: should return error"
5627
5628         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5629
5630         local ostidx=1
5631         local obduuid=$(ostuuid_from_index $ostidx)
5632         local found=$($LFS getstripe -r --obd $obduuid $dir |
5633                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5634
5635         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5636         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5637                 ((filenum--))
5638         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5639                 ((filenum--))
5640
5641         [[ $found -eq $filenum ]] ||
5642                 error "$LFS getstripe --obd: found $found expect $filenum"
5643         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5644                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5645                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5646                 error "$LFS getstripe --obd: should not show file on other obd"
5647         echo "$LFS getstripe --obd passed"
5648 }
5649 run_test 56a "check $LFS getstripe"
5650
5651 test_56b() {
5652         local dir=$DIR/$tdir
5653         local numdirs=3
5654
5655         test_mkdir $dir
5656         for i in $(seq $numdirs); do
5657                 test_mkdir $dir/dir$i
5658         done
5659
5660         # test lfs getdirstripe default mode is non-recursion, which is
5661         # different from lfs getstripe
5662         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5663
5664         [[ $dircnt -eq 1 ]] ||
5665                 error "$LFS getdirstripe: found $dircnt, not 1"
5666         dircnt=$($LFS getdirstripe --recursive $dir |
5667                 grep -c lmv_stripe_count)
5668         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5669                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5670 }
5671 run_test 56b "check $LFS getdirstripe"
5672
5673 test_56c() {
5674         remote_ost_nodsh && skip "remote OST with nodsh"
5675
5676         local ost_idx=0
5677         local ost_name=$(ostname_from_index $ost_idx)
5678         local old_status=$(ost_dev_status $ost_idx)
5679         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5680
5681         [[ -z "$old_status" ]] ||
5682                 skip_env "OST $ost_name is in $old_status status"
5683
5684         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5685         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5686                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5687         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5688                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5689                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5690         fi
5691
5692         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5693                 error "$LFS df -v showing inactive devices"
5694         sleep_maxage
5695
5696         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5697
5698         [[ "$new_status" =~ "D" ]] ||
5699                 error "$ost_name status is '$new_status', missing 'D'"
5700         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5701                 [[ "$new_status" =~ "N" ]] ||
5702                         error "$ost_name status is '$new_status', missing 'N'"
5703         fi
5704         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5705                 [[ "$new_status" =~ "f" ]] ||
5706                         error "$ost_name status is '$new_status', missing 'f'"
5707         fi
5708
5709         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5710         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5711                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5712         [[ -z "$p" ]] && restore_lustre_params < $p || true
5713         sleep_maxage
5714
5715         new_status=$(ost_dev_status $ost_idx)
5716         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5717                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5718         # can't check 'f' as devices may actually be on flash
5719 }
5720 run_test 56c "check 'lfs df' showing device status"
5721
5722 test_56d() {
5723         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5724         local osts=$($LFS df -v $MOUNT | grep -c OST)
5725
5726         $LFS df $MOUNT
5727
5728         (( mdts == MDSCOUNT )) ||
5729                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5730         (( osts == OSTCOUNT )) ||
5731                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5732 }
5733 run_test 56d "'lfs df -v' prints only configured devices"
5734
5735 NUMFILES=3
5736 NUMDIRS=3
5737 setup_56() {
5738         local local_tdir="$1"
5739         local local_numfiles="$2"
5740         local local_numdirs="$3"
5741         local dir_params="$4"
5742         local dir_stripe_params="$5"
5743
5744         if [ ! -d "$local_tdir" ] ; then
5745                 test_mkdir -p $dir_stripe_params $local_tdir
5746                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5747                 for i in $(seq $local_numfiles) ; do
5748                         touch $local_tdir/file$i
5749                 done
5750                 for i in $(seq $local_numdirs) ; do
5751                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5752                         for j in $(seq $local_numfiles) ; do
5753                                 touch $local_tdir/dir$i/file$j
5754                         done
5755                 done
5756         fi
5757 }
5758
5759 setup_56_special() {
5760         local local_tdir=$1
5761         local local_numfiles=$2
5762         local local_numdirs=$3
5763
5764         setup_56 $local_tdir $local_numfiles $local_numdirs
5765
5766         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5767                 for i in $(seq $local_numfiles) ; do
5768                         mknod $local_tdir/loop${i}b b 7 $i
5769                         mknod $local_tdir/null${i}c c 1 3
5770                         ln -s $local_tdir/file1 $local_tdir/link${i}
5771                 done
5772                 for i in $(seq $local_numdirs) ; do
5773                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5774                         mknod $local_tdir/dir$i/null${i}c c 1 3
5775                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5776                 done
5777         fi
5778 }
5779
5780 test_56g() {
5781         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5782         local expected=$(($NUMDIRS + 2))
5783
5784         setup_56 $dir $NUMFILES $NUMDIRS
5785
5786         # test lfs find with -name
5787         for i in $(seq $NUMFILES) ; do
5788                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5789
5790                 [ $nums -eq $expected ] ||
5791                         error "lfs find -name '*$i' $dir wrong: "\
5792                               "found $nums, expected $expected"
5793         done
5794 }
5795 run_test 56g "check lfs find -name"
5796
5797 test_56h() {
5798         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5799         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5800
5801         setup_56 $dir $NUMFILES $NUMDIRS
5802
5803         # test lfs find with ! -name
5804         for i in $(seq $NUMFILES) ; do
5805                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5806
5807                 [ $nums -eq $expected ] ||
5808                         error "lfs find ! -name '*$i' $dir wrong: "\
5809                               "found $nums, expected $expected"
5810         done
5811 }
5812 run_test 56h "check lfs find ! -name"
5813
5814 test_56i() {
5815         local dir=$DIR/$tdir
5816
5817         test_mkdir $dir
5818
5819         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5820         local out=$($cmd)
5821
5822         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5823 }
5824 run_test 56i "check 'lfs find -ost UUID' skips directories"
5825
5826 test_56j() {
5827         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5828
5829         setup_56_special $dir $NUMFILES $NUMDIRS
5830
5831         local expected=$((NUMDIRS + 1))
5832         local cmd="$LFS find -type d $dir"
5833         local nums=$($cmd | wc -l)
5834
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837 }
5838 run_test 56j "check lfs find -type d"
5839
5840 test_56k() {
5841         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5842
5843         setup_56_special $dir $NUMFILES $NUMDIRS
5844
5845         local expected=$(((NUMDIRS + 1) * NUMFILES))
5846         local cmd="$LFS find -type f $dir"
5847         local nums=$($cmd | wc -l)
5848
5849         [ $nums -eq $expected ] ||
5850                 error "'$cmd' wrong: found $nums, expected $expected"
5851 }
5852 run_test 56k "check lfs find -type f"
5853
5854 test_56l() {
5855         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5856
5857         setup_56_special $dir $NUMFILES $NUMDIRS
5858
5859         local expected=$((NUMDIRS + NUMFILES))
5860         local cmd="$LFS find -type b $dir"
5861         local nums=$($cmd | wc -l)
5862
5863         [ $nums -eq $expected ] ||
5864                 error "'$cmd' wrong: found $nums, expected $expected"
5865 }
5866 run_test 56l "check lfs find -type b"
5867
5868 test_56m() {
5869         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5870
5871         setup_56_special $dir $NUMFILES $NUMDIRS
5872
5873         local expected=$((NUMDIRS + NUMFILES))
5874         local cmd="$LFS find -type c $dir"
5875         local nums=$($cmd | wc -l)
5876         [ $nums -eq $expected ] ||
5877                 error "'$cmd' wrong: found $nums, expected $expected"
5878 }
5879 run_test 56m "check lfs find -type c"
5880
5881 test_56n() {
5882         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5883         setup_56_special $dir $NUMFILES $NUMDIRS
5884
5885         local expected=$((NUMDIRS + NUMFILES))
5886         local cmd="$LFS find -type l $dir"
5887         local nums=$($cmd | wc -l)
5888
5889         [ $nums -eq $expected ] ||
5890                 error "'$cmd' wrong: found $nums, expected $expected"
5891 }
5892 run_test 56n "check lfs find -type l"
5893
5894 test_56o() {
5895         local dir=$DIR/$tdir
5896
5897         setup_56 $dir $NUMFILES $NUMDIRS
5898         utime $dir/file1 > /dev/null || error "utime (1)"
5899         utime $dir/file2 > /dev/null || error "utime (2)"
5900         utime $dir/dir1 > /dev/null || error "utime (3)"
5901         utime $dir/dir2 > /dev/null || error "utime (4)"
5902         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5903         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5904
5905         local expected=4
5906         local nums=$($LFS find -mtime +0 $dir | wc -l)
5907
5908         [ $nums -eq $expected ] ||
5909                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5910
5911         expected=12
5912         cmd="$LFS find -mtime 0 $dir"
5913         nums=$($cmd | wc -l)
5914         [ $nums -eq $expected ] ||
5915                 error "'$cmd' wrong: found $nums, expected $expected"
5916 }
5917 run_test 56o "check lfs find -mtime for old files"
5918
5919 test_56ob() {
5920         local dir=$DIR/$tdir
5921         local expected=1
5922         local count=0
5923
5924         # just to make sure there is something that won't be found
5925         test_mkdir $dir
5926         touch $dir/$tfile.now
5927
5928         for age in year week day hour min; do
5929                 count=$((count + 1))
5930
5931                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5932                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5933                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5934
5935                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5936                 local nums=$($cmd | wc -l)
5937                 [ $nums -eq $expected ] ||
5938                         error "'$cmd' wrong: found $nums, expected $expected"
5939
5940                 cmd="$LFS find $dir -atime $count${age:0:1}"
5941                 nums=$($cmd | wc -l)
5942                 [ $nums -eq $expected ] ||
5943                         error "'$cmd' wrong: found $nums, expected $expected"
5944         done
5945
5946         sleep 2
5947         cmd="$LFS find $dir -ctime +1s -type f"
5948         nums=$($cmd | wc -l)
5949         (( $nums == $count * 2 + 1)) ||
5950                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5951 }
5952 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5953
5954 test_newerXY_base() {
5955         local x=$1
5956         local y=$2
5957         local dir=$DIR/$tdir
5958         local ref
5959         local negref
5960
5961         if [ $y == "t" ]; then
5962                 if [ $x == "b" ]; then
5963                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5964                 else
5965                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5966                 fi
5967         else
5968                 ref=$DIR/$tfile.newer.$x$y
5969                 touch $ref || error "touch $ref failed"
5970         fi
5971         sleep 2
5972         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5973         sleep 2
5974         if [ $y == "t" ]; then
5975                 if [ $x == "b" ]; then
5976                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5977                 else
5978                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5979                 fi
5980         else
5981                 negref=$DIR/$tfile.negnewer.$x$y
5982                 touch $negref || error "touch $negref failed"
5983         fi
5984
5985         local cmd="$LFS find $dir -newer$x$y $ref"
5986         local nums=$(eval $cmd | wc -l)
5987         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5988
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         cmd="$LFS find $dir ! -newer$x$y $negref"
5993         nums=$(eval $cmd | wc -l)
5994         [ $nums -eq $expected ] ||
5995                 error "'$cmd' wrong: found $nums, expected $expected"
5996
5997         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5998         nums=$(eval $cmd | wc -l)
5999         [ $nums -eq $expected ] ||
6000                 error "'$cmd' wrong: found $nums, expected $expected"
6001
6002         rm -rf $DIR/*
6003 }
6004
6005 test_56oc() {
6006         test_newerXY_base "b" "t"
6007         test_newerXY_base "a" "a"
6008         test_newerXY_base "a" "m"
6009         test_newerXY_base "a" "c"
6010         test_newerXY_base "m" "a"
6011         test_newerXY_base "m" "m"
6012         test_newerXY_base "m" "c"
6013         test_newerXY_base "c" "a"
6014         test_newerXY_base "c" "m"
6015         test_newerXY_base "c" "c"
6016         test_newerXY_base "b" "b"
6017         test_newerXY_base "a" "t"
6018         test_newerXY_base "m" "t"
6019         test_newerXY_base "c" "t"
6020         test_newerXY_base "b" "t"
6021 }
6022 run_test 56oc "check lfs find -newerXY work"
6023
6024 btime_supported() {
6025         local dir=$DIR/$tdir
6026         local rc
6027
6028         mkdir -p $dir
6029         touch $dir/$tfile
6030         $LFS find $dir -btime -1d -type f
6031         rc=$?
6032         rm -rf $dir
6033         return $rc
6034 }
6035
6036 test_56od() {
6037         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6038                 ! btime_supported && skip "btime unsupported on MDS"
6039
6040         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6041                 ! btime_supported && skip "btime unsupported on clients"
6042
6043         local dir=$DIR/$tdir
6044         local ref=$DIR/$tfile.ref
6045         local negref=$DIR/$tfile.negref
6046
6047         mkdir $dir || error "mkdir $dir failed"
6048         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6049         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6050         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6051         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6052         touch $ref || error "touch $ref failed"
6053         # sleep 3 seconds at least
6054         sleep 3
6055
6056         local before=$(do_facet mds1 date +%s)
6057         local skew=$(($(date +%s) - before + 1))
6058
6059         if (( skew < 0 && skew > -5 )); then
6060                 sleep $((0 - skew + 1))
6061                 skew=0
6062         fi
6063
6064         # Set the dir stripe params to limit files all on MDT0,
6065         # otherwise we need to calc the max clock skew between
6066         # the client and MDTs.
6067         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6068         sleep 2
6069         touch $negref || error "touch $negref failed"
6070
6071         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6072         local nums=$($cmd | wc -l)
6073         local expected=$(((NUMFILES + 1) * NUMDIRS))
6074
6075         [ $nums -eq $expected ] ||
6076                 error "'$cmd' wrong: found $nums, expected $expected"
6077
6078         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6079         nums=$($cmd | wc -l)
6080         expected=$((NUMFILES + 1))
6081         [ $nums -eq $expected ] ||
6082                 error "'$cmd' wrong: found $nums, expected $expected"
6083
6084         [ $skew -lt 0 ] && return
6085
6086         local after=$(do_facet mds1 date +%s)
6087         local age=$((after - before + 1 + skew))
6088
6089         cmd="$LFS find $dir -btime -${age}s -type f"
6090         nums=$($cmd | wc -l)
6091         expected=$(((NUMFILES + 1) * NUMDIRS))
6092
6093         echo "Clock skew between client and server: $skew, age:$age"
6094         [ $nums -eq $expected ] ||
6095                 error "'$cmd' wrong: found $nums, expected $expected"
6096
6097         expected=$(($NUMDIRS + 1))
6098         cmd="$LFS find $dir -btime -${age}s -type d"
6099         nums=$($cmd | wc -l)
6100         [ $nums -eq $expected ] ||
6101                 error "'$cmd' wrong: found $nums, expected $expected"
6102         rm -f $ref $negref || error "Failed to remove $ref $negref"
6103 }
6104 run_test 56od "check lfs find -btime with units"
6105
6106 test_56p() {
6107         [ $RUNAS_ID -eq $UID ] &&
6108                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6109
6110         local dir=$DIR/$tdir
6111
6112         setup_56 $dir $NUMFILES $NUMDIRS
6113         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6114
6115         local expected=$NUMFILES
6116         local cmd="$LFS find -uid $RUNAS_ID $dir"
6117         local nums=$($cmd | wc -l)
6118
6119         [ $nums -eq $expected ] ||
6120                 error "'$cmd' wrong: found $nums, expected $expected"
6121
6122         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6123         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6124         nums=$($cmd | wc -l)
6125         [ $nums -eq $expected ] ||
6126                 error "'$cmd' wrong: found $nums, expected $expected"
6127 }
6128 run_test 56p "check lfs find -uid and ! -uid"
6129
6130 test_56q() {
6131         [ $RUNAS_ID -eq $UID ] &&
6132                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6133
6134         local dir=$DIR/$tdir
6135
6136         setup_56 $dir $NUMFILES $NUMDIRS
6137         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6138
6139         local expected=$NUMFILES
6140         local cmd="$LFS find -gid $RUNAS_GID $dir"
6141         local nums=$($cmd | wc -l)
6142
6143         [ $nums -eq $expected ] ||
6144                 error "'$cmd' wrong: found $nums, expected $expected"
6145
6146         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6147         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6148         nums=$($cmd | wc -l)
6149         [ $nums -eq $expected ] ||
6150                 error "'$cmd' wrong: found $nums, expected $expected"
6151 }
6152 run_test 56q "check lfs find -gid and ! -gid"
6153
6154 test_56r() {
6155         local dir=$DIR/$tdir
6156
6157         setup_56 $dir $NUMFILES $NUMDIRS
6158
6159         local expected=12
6160         local cmd="$LFS find -size 0 -type f -lazy $dir"
6161         local nums=$($cmd | wc -l)
6162
6163         [ $nums -eq $expected ] ||
6164                 error "'$cmd' wrong: found $nums, expected $expected"
6165         cmd="$LFS find -size 0 -type f $dir"
6166         nums=$($cmd | wc -l)
6167         [ $nums -eq $expected ] ||
6168                 error "'$cmd' wrong: found $nums, expected $expected"
6169
6170         expected=0
6171         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6172         nums=$($cmd | wc -l)
6173         [ $nums -eq $expected ] ||
6174                 error "'$cmd' wrong: found $nums, expected $expected"
6175         cmd="$LFS find ! -size 0 -type f $dir"
6176         nums=$($cmd | wc -l)
6177         [ $nums -eq $expected ] ||
6178                 error "'$cmd' wrong: found $nums, expected $expected"
6179
6180         echo "test" > $dir/$tfile
6181         echo "test2" > $dir/$tfile.2 && sync
6182         expected=1
6183         cmd="$LFS find -size 5 -type f -lazy $dir"
6184         nums=$($cmd | wc -l)
6185         [ $nums -eq $expected ] ||
6186                 error "'$cmd' wrong: found $nums, expected $expected"
6187         cmd="$LFS find -size 5 -type f $dir"
6188         nums=$($cmd | wc -l)
6189         [ $nums -eq $expected ] ||
6190                 error "'$cmd' wrong: found $nums, expected $expected"
6191
6192         expected=1
6193         cmd="$LFS find -size +5 -type f -lazy $dir"
6194         nums=$($cmd | wc -l)
6195         [ $nums -eq $expected ] ||
6196                 error "'$cmd' wrong: found $nums, expected $expected"
6197         cmd="$LFS find -size +5 -type f $dir"
6198         nums=$($cmd | wc -l)
6199         [ $nums -eq $expected ] ||
6200                 error "'$cmd' wrong: found $nums, expected $expected"
6201
6202         expected=2
6203         cmd="$LFS find -size +0 -type f -lazy $dir"
6204         nums=$($cmd | wc -l)
6205         [ $nums -eq $expected ] ||
6206                 error "'$cmd' wrong: found $nums, expected $expected"
6207         cmd="$LFS find -size +0 -type f $dir"
6208         nums=$($cmd | wc -l)
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211
6212         expected=2
6213         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6214         nums=$($cmd | wc -l)
6215         [ $nums -eq $expected ] ||
6216                 error "'$cmd' wrong: found $nums, expected $expected"
6217         cmd="$LFS find ! -size -5 -type f $dir"
6218         nums=$($cmd | wc -l)
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221
6222         expected=12
6223         cmd="$LFS find -size -5 -type f -lazy $dir"
6224         nums=$($cmd | wc -l)
6225         [ $nums -eq $expected ] ||
6226                 error "'$cmd' wrong: found $nums, expected $expected"
6227         cmd="$LFS find -size -5 -type f $dir"
6228         nums=$($cmd | wc -l)
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231 }
6232 run_test 56r "check lfs find -size works"
6233
6234 test_56ra_sub() {
6235         local expected=$1
6236         local glimpses=$2
6237         local cmd="$3"
6238
6239         cancel_lru_locks $OSC
6240
6241         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6242         local nums=$($cmd | wc -l)
6243
6244         [ $nums -eq $expected ] ||
6245                 error "'$cmd' wrong: found $nums, expected $expected"
6246
6247         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6248
6249         if (( rpcs_before + glimpses != rpcs_after )); then
6250                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6251                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6252
6253                 if [[ $glimpses == 0 ]]; then
6254                         error "'$cmd' should not send glimpse RPCs to OST"
6255                 else
6256                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6257                 fi
6258         fi
6259 }
6260
6261 test_56ra() {
6262         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6263                 skip "MDS < 2.12.58 doesn't return LSOM data"
6264         local dir=$DIR/$tdir
6265         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6266
6267         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6268
6269         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6270         $LCTL set_param -n llite.*.statahead_agl=0
6271         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6272
6273         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6274         # open and close all files to ensure LSOM is updated
6275         cancel_lru_locks $OSC
6276         find $dir -type f | xargs cat > /dev/null
6277
6278         #   expect_found  glimpse_rpcs  command_to_run
6279         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6280         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6281         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6282         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6283
6284         echo "test" > $dir/$tfile
6285         echo "test2" > $dir/$tfile.2 && sync
6286         cancel_lru_locks $OSC
6287         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6288
6289         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6290         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6291         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6292         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6293
6294         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6295         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6296         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6297         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6298         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6299         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6300 }
6301 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6302
6303 test_56rb() {
6304         local dir=$DIR/$tdir
6305         local tmp=$TMP/$tfile.log
6306         local mdt_idx;
6307
6308         test_mkdir -p $dir || error "failed to mkdir $dir"
6309         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6310                 error "failed to setstripe $dir/$tfile"
6311         mdt_idx=$($LFS getdirstripe -i $dir)
6312         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6313
6314         stack_trap "rm -f $tmp" EXIT
6315         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6316         ! grep -q obd_uuid $tmp ||
6317                 error "failed to find --size +100K --ost 0 $dir"
6318         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6319         ! grep -q obd_uuid $tmp ||
6320                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6321 }
6322 run_test 56rb "check lfs find --size --ost/--mdt works"
6323
6324 test_56s() { # LU-611 #LU-9369
6325         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6326
6327         local dir=$DIR/$tdir
6328         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6329
6330         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6331         for i in $(seq $NUMDIRS); do
6332                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6333         done
6334
6335         local expected=$NUMDIRS
6336         local cmd="$LFS find -c $OSTCOUNT $dir"
6337         local nums=$($cmd | wc -l)
6338
6339         [ $nums -eq $expected ] || {
6340                 $LFS getstripe -R $dir
6341                 error "'$cmd' wrong: found $nums, expected $expected"
6342         }
6343
6344         expected=$((NUMDIRS + onestripe))
6345         cmd="$LFS find -stripe-count +0 -type f $dir"
6346         nums=$($cmd | wc -l)
6347         [ $nums -eq $expected ] || {
6348                 $LFS getstripe -R $dir
6349                 error "'$cmd' wrong: found $nums, expected $expected"
6350         }
6351
6352         expected=$onestripe
6353         cmd="$LFS find -stripe-count 1 -type f $dir"
6354         nums=$($cmd | wc -l)
6355         [ $nums -eq $expected ] || {
6356                 $LFS getstripe -R $dir
6357                 error "'$cmd' wrong: found $nums, expected $expected"
6358         }
6359
6360         cmd="$LFS find -stripe-count -2 -type f $dir"
6361         nums=$($cmd | wc -l)
6362         [ $nums -eq $expected ] || {
6363                 $LFS getstripe -R $dir
6364                 error "'$cmd' wrong: found $nums, expected $expected"
6365         }
6366
6367         expected=0
6368         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6369         nums=$($cmd | wc -l)
6370         [ $nums -eq $expected ] || {
6371                 $LFS getstripe -R $dir
6372                 error "'$cmd' wrong: found $nums, expected $expected"
6373         }
6374 }
6375 run_test 56s "check lfs find -stripe-count works"
6376
6377 test_56t() { # LU-611 #LU-9369
6378         local dir=$DIR/$tdir
6379
6380         setup_56 $dir 0 $NUMDIRS
6381         for i in $(seq $NUMDIRS); do
6382                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6383         done
6384
6385         local expected=$NUMDIRS
6386         local cmd="$LFS find -S 8M $dir"
6387         local nums=$($cmd | wc -l)
6388
6389         [ $nums -eq $expected ] || {
6390                 $LFS getstripe -R $dir
6391                 error "'$cmd' wrong: found $nums, expected $expected"
6392         }
6393         rm -rf $dir
6394
6395         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6396
6397         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6398
6399         expected=$(((NUMDIRS + 1) * NUMFILES))
6400         cmd="$LFS find -stripe-size 512k -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] ||
6403                 error "'$cmd' wrong: found $nums, expected $expected"
6404
6405         cmd="$LFS find -stripe-size +320k -type f $dir"
6406         nums=$($cmd | wc -l)
6407         [ $nums -eq $expected ] ||
6408                 error "'$cmd' wrong: found $nums, expected $expected"
6409
6410         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6411         cmd="$LFS find -stripe-size +200k -type f $dir"
6412         nums=$($cmd | wc -l)
6413         [ $nums -eq $expected ] ||
6414                 error "'$cmd' wrong: found $nums, expected $expected"
6415
6416         cmd="$LFS find -stripe-size -640k -type f $dir"
6417         nums=$($cmd | wc -l)
6418         [ $nums -eq $expected ] ||
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420
6421         expected=4
6422         cmd="$LFS find -stripe-size 256k -type f $dir"
6423         nums=$($cmd | wc -l)
6424         [ $nums -eq $expected ] ||
6425                 error "'$cmd' wrong: found $nums, expected $expected"
6426
6427         cmd="$LFS find -stripe-size -320k -type f $dir"
6428         nums=$($cmd | wc -l)
6429         [ $nums -eq $expected ] ||
6430                 error "'$cmd' wrong: found $nums, expected $expected"
6431
6432         expected=0
6433         cmd="$LFS find -stripe-size 1024k -type f $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437 }
6438 run_test 56t "check lfs find -stripe-size works"
6439
6440 test_56u() { # LU-611
6441         local dir=$DIR/$tdir
6442
6443         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6444
6445         if [[ $OSTCOUNT -gt 1 ]]; then
6446                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6447                 onestripe=4
6448         else
6449                 onestripe=0
6450         fi
6451
6452         local expected=$(((NUMDIRS + 1) * NUMFILES))
6453         local cmd="$LFS find -stripe-index 0 -type f $dir"
6454         local nums=$($cmd | wc -l)
6455
6456         [ $nums -eq $expected ] ||
6457                 error "'$cmd' wrong: found $nums, expected $expected"
6458
6459         expected=$onestripe
6460         cmd="$LFS find -stripe-index 1 -type f $dir"
6461         nums=$($cmd | wc -l)
6462         [ $nums -eq $expected ] ||
6463                 error "'$cmd' wrong: found $nums, expected $expected"
6464
6465         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6466         nums=$($cmd | wc -l)
6467         [ $nums -eq $expected ] ||
6468                 error "'$cmd' wrong: found $nums, expected $expected"
6469
6470         expected=0
6471         # This should produce an error and not return any files
6472         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6473         nums=$($cmd 2>/dev/null | wc -l)
6474         [ $nums -eq $expected ] ||
6475                 error "'$cmd' wrong: found $nums, expected $expected"
6476
6477         if [[ $OSTCOUNT -gt 1 ]]; then
6478                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6479                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6480                 nums=$($cmd | wc -l)
6481                 [ $nums -eq $expected ] ||
6482                         error "'$cmd' wrong: found $nums, expected $expected"
6483         fi
6484 }
6485 run_test 56u "check lfs find -stripe-index works"
6486
6487 test_56v() {
6488         local mdt_idx=0
6489         local dir=$DIR/$tdir
6490
6491         setup_56 $dir $NUMFILES $NUMDIRS
6492
6493         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6494         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6495
6496         for file in $($LFS find -m $UUID $dir); do
6497                 file_midx=$($LFS getstripe -m $file)
6498                 [ $file_midx -eq $mdt_idx ] ||
6499                         error "lfs find -m $UUID != getstripe -m $file_midx"
6500         done
6501 }
6502 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6503
6504 test_56w() {
6505         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6507
6508         local dir=$DIR/$tdir
6509
6510         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6511
6512         local stripe_size=$($LFS getstripe -S -d $dir) ||
6513                 error "$LFS getstripe -S -d $dir failed"
6514         stripe_size=${stripe_size%% *}
6515
6516         local file_size=$((stripe_size * OSTCOUNT))
6517         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6518         local required_space=$((file_num * file_size))
6519         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6520                            head -n1)
6521         [[ $free_space -le $((required_space / 1024)) ]] &&
6522                 skip_env "need $required_space, have $free_space kbytes"
6523
6524         local dd_bs=65536
6525         local dd_count=$((file_size / dd_bs))
6526
6527         # write data into the files
6528         local i
6529         local j
6530         local file
6531
6532         for i in $(seq $NUMFILES); do
6533                 file=$dir/file$i
6534                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6535                         error "write data into $file failed"
6536         done
6537         for i in $(seq $NUMDIRS); do
6538                 for j in $(seq $NUMFILES); do
6539                         file=$dir/dir$i/file$j
6540                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6541                                 error "write data into $file failed"
6542                 done
6543         done
6544
6545         # $LFS_MIGRATE will fail if hard link migration is unsupported
6546         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6547                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6548                         error "creating links to $dir/dir1/file1 failed"
6549         fi
6550
6551         local expected=-1
6552
6553         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6554
6555         # lfs_migrate file
6556         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6557
6558         echo "$cmd"
6559         eval $cmd || error "$cmd failed"
6560
6561         check_stripe_count $dir/file1 $expected
6562
6563         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6564         then
6565                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6566                 # OST 1 if it is on OST 0. This file is small enough to
6567                 # be on only one stripe.
6568                 file=$dir/migr_1_ost
6569                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6570                         error "write data into $file failed"
6571                 local obdidx=$($LFS getstripe -i $file)
6572                 local oldmd5=$(md5sum $file)
6573                 local newobdidx=0
6574
6575                 [[ $obdidx -eq 0 ]] && newobdidx=1
6576                 cmd="$LFS migrate -i $newobdidx $file"
6577                 echo $cmd
6578                 eval $cmd || error "$cmd failed"
6579
6580                 local realobdix=$($LFS getstripe -i $file)
6581                 local newmd5=$(md5sum $file)
6582
6583                 [[ $newobdidx -ne $realobdix ]] &&
6584                         error "new OST is different (was=$obdidx, "\
6585                               "wanted=$newobdidx, got=$realobdix)"
6586                 [[ "$oldmd5" != "$newmd5" ]] &&
6587                         error "md5sum differ: $oldmd5, $newmd5"
6588         fi
6589
6590         # lfs_migrate dir
6591         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6592         echo "$cmd"
6593         eval $cmd || error "$cmd failed"
6594
6595         for j in $(seq $NUMFILES); do
6596                 check_stripe_count $dir/dir1/file$j $expected
6597         done
6598
6599         # lfs_migrate works with lfs find
6600         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6601              $LFS_MIGRATE -y -c $expected"
6602         echo "$cmd"
6603         eval $cmd || error "$cmd failed"
6604
6605         for i in $(seq 2 $NUMFILES); do
6606                 check_stripe_count $dir/file$i $expected
6607         done
6608         for i in $(seq 2 $NUMDIRS); do
6609                 for j in $(seq $NUMFILES); do
6610                 check_stripe_count $dir/dir$i/file$j $expected
6611                 done
6612         done
6613 }
6614 run_test 56w "check lfs_migrate -c stripe_count works"
6615
6616 test_56wb() {
6617         local file1=$DIR/$tdir/file1
6618         local create_pool=false
6619         local initial_pool=$($LFS getstripe -p $DIR)
6620         local pool_list=()
6621         local pool=""
6622
6623         echo -n "Creating test dir..."
6624         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6625         echo "done."
6626
6627         echo -n "Creating test file..."
6628         touch $file1 || error "cannot create file"
6629         echo "done."
6630
6631         echo -n "Detecting existing pools..."
6632         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6633
6634         if [ ${#pool_list[@]} -gt 0 ]; then
6635                 echo "${pool_list[@]}"
6636                 for thispool in "${pool_list[@]}"; do
6637                         if [[ -z "$initial_pool" ||
6638                               "$initial_pool" != "$thispool" ]]; then
6639                                 pool="$thispool"
6640                                 echo "Using existing pool '$pool'"
6641                                 break
6642                         fi
6643                 done
6644         else
6645                 echo "none detected."
6646         fi
6647         if [ -z "$pool" ]; then
6648                 pool=${POOL:-testpool}
6649                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6650                 echo -n "Creating pool '$pool'..."
6651                 create_pool=true
6652                 pool_add $pool &> /dev/null ||
6653                         error "pool_add failed"
6654                 echo "done."
6655
6656                 echo -n "Adding target to pool..."
6657                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6658                         error "pool_add_targets failed"
6659                 echo "done."
6660         fi
6661
6662         echo -n "Setting pool using -p option..."
6663         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6664                 error "migrate failed rc = $?"
6665         echo "done."
6666
6667         echo -n "Verifying test file is in pool after migrating..."
6668         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6669                 error "file was not migrated to pool $pool"
6670         echo "done."
6671
6672         echo -n "Removing test file from pool '$pool'..."
6673         # "lfs migrate $file" won't remove the file from the pool
6674         # until some striping information is changed.
6675         $LFS migrate -c 1 $file1 &> /dev/null ||
6676                 error "cannot remove from pool"
6677         [ "$($LFS getstripe -p $file1)" ] &&
6678                 error "pool still set"
6679         echo "done."
6680
6681         echo -n "Setting pool using --pool option..."
6682         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6683                 error "migrate failed rc = $?"
6684         echo "done."
6685
6686         # Clean up
6687         rm -f $file1
6688         if $create_pool; then
6689                 destroy_test_pools 2> /dev/null ||
6690                         error "destroy test pools failed"
6691         fi
6692 }
6693 run_test 56wb "check lfs_migrate pool support"
6694
6695 test_56wc() {
6696         local file1="$DIR/$tdir/file1"
6697         local parent_ssize
6698         local parent_scount
6699         local cur_ssize
6700         local cur_scount
6701         local orig_ssize
6702
6703         echo -n "Creating test dir..."
6704         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6705         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6706                 error "cannot set stripe by '-S 1M -c 1'"
6707         echo "done"
6708
6709         echo -n "Setting initial stripe for test file..."
6710         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6711                 error "cannot set stripe"
6712         cur_ssize=$($LFS getstripe -S "$file1")
6713         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6714         echo "done."
6715
6716         # File currently set to -S 512K -c 1
6717
6718         # Ensure -c and -S options are rejected when -R is set
6719         echo -n "Verifying incompatible options are detected..."
6720         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6721                 error "incompatible -c and -R options not detected"
6722         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6723                 error "incompatible -S and -R options not detected"
6724         echo "done."
6725
6726         # Ensure unrecognized options are passed through to 'lfs migrate'
6727         echo -n "Verifying -S option is passed through to lfs migrate..."
6728         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6729                 error "migration failed"
6730         cur_ssize=$($LFS getstripe -S "$file1")
6731         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6732         echo "done."
6733
6734         # File currently set to -S 1M -c 1
6735
6736         # Ensure long options are supported
6737         echo -n "Verifying long options supported..."
6738         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6739                 error "long option without argument not supported"
6740         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6741                 error "long option with argument not supported"
6742         cur_ssize=$($LFS getstripe -S "$file1")
6743         [ $cur_ssize -eq 524288 ] ||
6744                 error "migrate --stripe-size $cur_ssize != 524288"
6745         echo "done."
6746
6747         # File currently set to -S 512K -c 1
6748
6749         if [ "$OSTCOUNT" -gt 1 ]; then
6750                 echo -n "Verifying explicit stripe count can be set..."
6751                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6752                         error "migrate failed"
6753                 cur_scount=$($LFS getstripe -c "$file1")
6754                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6755                 echo "done."
6756         fi
6757
6758         # File currently set to -S 512K -c 1 or -S 512K -c 2
6759
6760         # Ensure parent striping is used if -R is set, and no stripe
6761         # count or size is specified
6762         echo -n "Setting stripe for parent directory..."
6763         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6764                 error "cannot set stripe '-S 2M -c 1'"
6765         echo "done."
6766
6767         echo -n "Verifying restripe option uses parent stripe settings..."
6768         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6769         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6770         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6771                 error "migrate failed"
6772         cur_ssize=$($LFS getstripe -S "$file1")
6773         [ $cur_ssize -eq $parent_ssize ] ||
6774                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6775         cur_scount=$($LFS getstripe -c "$file1")
6776         [ $cur_scount -eq $parent_scount ] ||
6777                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6778         echo "done."
6779
6780         # File currently set to -S 1M -c 1
6781
6782         # Ensure striping is preserved if -R is not set, and no stripe
6783         # count or size is specified
6784         echo -n "Verifying striping size preserved when not specified..."
6785         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6786         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6787                 error "cannot set stripe on parent directory"
6788         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6789                 error "migrate failed"
6790         cur_ssize=$($LFS getstripe -S "$file1")
6791         [ $cur_ssize -eq $orig_ssize ] ||
6792                 error "migrate by default $cur_ssize != $orig_ssize"
6793         echo "done."
6794
6795         # Ensure file name properly detected when final option has no argument
6796         echo -n "Verifying file name properly detected..."
6797         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6798                 error "file name interpreted as option argument"
6799         echo "done."
6800
6801         # Clean up
6802         rm -f "$file1"
6803 }
6804 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6805
6806 test_56wd() {
6807         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6808
6809         local file1=$DIR/$tdir/file1
6810
6811         echo -n "Creating test dir..."
6812         test_mkdir $DIR/$tdir || error "cannot create dir"
6813         echo "done."
6814
6815         echo -n "Creating test file..."
6816         touch $file1
6817         echo "done."
6818
6819         # Ensure 'lfs migrate' will fail by using a non-existent option,
6820         # and make sure rsync is not called to recover
6821         echo -n "Make sure --no-rsync option works..."
6822         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6823                 grep -q 'refusing to fall back to rsync' ||
6824                 error "rsync was called with --no-rsync set"
6825         echo "done."
6826
6827         # Ensure rsync is called without trying 'lfs migrate' first
6828         echo -n "Make sure --rsync option works..."
6829         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6830                 grep -q 'falling back to rsync' &&
6831                 error "lfs migrate was called with --rsync set"
6832         echo "done."
6833
6834         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6835         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6836                 grep -q 'at the same time' ||
6837                 error "--rsync and --no-rsync accepted concurrently"
6838         echo "done."
6839
6840         # Clean up
6841         rm -f $file1
6842 }
6843 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6844
6845 test_56we() {
6846         local td=$DIR/$tdir
6847         local tf=$td/$tfile
6848
6849         test_mkdir $td || error "cannot create $td"
6850         touch $tf || error "cannot touch $tf"
6851
6852         echo -n "Make sure --non-direct|-D works..."
6853         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6854                 grep -q "lfs migrate --non-direct" ||
6855                 error "--non-direct option cannot work correctly"
6856         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6857                 grep -q "lfs migrate -D" ||
6858                 error "-D option cannot work correctly"
6859         echo "done."
6860 }
6861 run_test 56we "check lfs_migrate --non-direct|-D support"
6862
6863 test_56x() {
6864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6865         check_swap_layouts_support
6866
6867         local dir=$DIR/$tdir
6868         local ref1=/etc/passwd
6869         local file1=$dir/file1
6870
6871         test_mkdir $dir || error "creating dir $dir"
6872         $LFS setstripe -c 2 $file1
6873         cp $ref1 $file1
6874         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6875         stripe=$($LFS getstripe -c $file1)
6876         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6877         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6878
6879         # clean up
6880         rm -f $file1
6881 }
6882 run_test 56x "lfs migration support"
6883
6884 test_56xa() {
6885         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6886         check_swap_layouts_support
6887
6888         local dir=$DIR/$tdir/$testnum
6889
6890         test_mkdir -p $dir
6891
6892         local ref1=/etc/passwd
6893         local file1=$dir/file1
6894
6895         $LFS setstripe -c 2 $file1
6896         cp $ref1 $file1
6897         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6898
6899         local stripe=$($LFS getstripe -c $file1)
6900
6901         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6902         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6903
6904         # clean up
6905         rm -f $file1
6906 }
6907 run_test 56xa "lfs migration --block support"
6908
6909 check_migrate_links() {
6910         local dir="$1"
6911         local file1="$dir/file1"
6912         local begin="$2"
6913         local count="$3"
6914         local runas="$4"
6915         local total_count=$(($begin + $count - 1))
6916         local symlink_count=10
6917         local uniq_count=10
6918
6919         if [ ! -f "$file1" ]; then
6920                 echo -n "creating initial file..."
6921                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6922                         error "cannot setstripe initial file"
6923                 echo "done"
6924
6925                 echo -n "creating symlinks..."
6926                 for s in $(seq 1 $symlink_count); do
6927                         ln -s "$file1" "$dir/slink$s" ||
6928                                 error "cannot create symlinks"
6929                 done
6930                 echo "done"
6931
6932                 echo -n "creating nonlinked files..."
6933                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6934                         error "cannot create nonlinked files"
6935                 echo "done"
6936         fi
6937
6938         # create hard links
6939         if [ ! -f "$dir/file$total_count" ]; then
6940                 echo -n "creating hard links $begin:$total_count..."
6941                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6942                         /dev/null || error "cannot create hard links"
6943                 echo "done"
6944         fi
6945
6946         echo -n "checking number of hard links listed in xattrs..."
6947         local fid=$($LFS getstripe -F "$file1")
6948         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6949
6950         echo "${#paths[*]}"
6951         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6952                         skip "hard link list has unexpected size, skipping test"
6953         fi
6954         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6955                         error "link names should exceed xattrs size"
6956         fi
6957
6958         echo -n "migrating files..."
6959         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6960         local rc=$?
6961         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6962         echo "done"
6963
6964         # make sure all links have been properly migrated
6965         echo -n "verifying files..."
6966         fid=$($LFS getstripe -F "$file1") ||
6967                 error "cannot get fid for file $file1"
6968         for i in $(seq 2 $total_count); do
6969                 local fid2=$($LFS getstripe -F $dir/file$i)
6970
6971                 [ "$fid2" == "$fid" ] ||
6972                         error "migrated hard link has mismatched FID"
6973         done
6974
6975         # make sure hard links were properly detected, and migration was
6976         # performed only once for the entire link set; nonlinked files should
6977         # also be migrated
6978         local actual=$(grep -c 'done' <<< "$migrate_out")
6979         local expected=$(($uniq_count + 1))
6980
6981         [ "$actual" -eq  "$expected" ] ||
6982                 error "hard links individually migrated ($actual != $expected)"
6983
6984         # make sure the correct number of hard links are present
6985         local hardlinks=$(stat -c '%h' "$file1")
6986
6987         [ $hardlinks -eq $total_count ] ||
6988                 error "num hard links $hardlinks != $total_count"
6989         echo "done"
6990
6991         return 0
6992 }
6993
6994 test_56xb() {
6995         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6996                 skip "Need MDS version at least 2.10.55"
6997
6998         local dir="$DIR/$tdir"
6999
7000         test_mkdir "$dir" || error "cannot create dir $dir"
7001
7002         echo "testing lfs migrate mode when all links fit within xattrs"
7003         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7004
7005         echo "testing rsync mode when all links fit within xattrs"
7006         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7007
7008         echo "testing lfs migrate mode when all links do not fit within xattrs"
7009         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7010
7011         echo "testing rsync mode when all links do not fit within xattrs"
7012         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7013
7014         chown -R $RUNAS_ID $dir
7015         echo "testing non-root lfs migrate mode when not all links are in xattr"
7016         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7017
7018         # clean up
7019         rm -rf $dir
7020 }
7021 run_test 56xb "lfs migration hard link support"
7022
7023 test_56xc() {
7024         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7025
7026         local dir="$DIR/$tdir"
7027
7028         test_mkdir "$dir" || error "cannot create dir $dir"
7029
7030         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7031         echo -n "Setting initial stripe for 20MB test file..."
7032         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7033                 error "cannot setstripe 20MB file"
7034         echo "done"
7035         echo -n "Sizing 20MB test file..."
7036         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7037         echo "done"
7038         echo -n "Verifying small file autostripe count is 1..."
7039         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7040                 error "cannot migrate 20MB file"
7041         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7042                 error "cannot get stripe for $dir/20mb"
7043         [ $stripe_count -eq 1 ] ||
7044                 error "unexpected stripe count $stripe_count for 20MB file"
7045         rm -f "$dir/20mb"
7046         echo "done"
7047
7048         # Test 2: File is small enough to fit within the available space on
7049         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7050         # have at least an additional 1KB for each desired stripe for test 3
7051         echo -n "Setting stripe for 1GB test file..."
7052         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7053         echo "done"
7054         echo -n "Sizing 1GB test file..."
7055         # File size is 1GB + 3KB
7056         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7057         echo "done"
7058
7059         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7060         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7061         if (( avail > 524288 * OSTCOUNT )); then
7062                 echo -n "Migrating 1GB file..."
7063                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7064                         error "cannot migrate 1GB file"
7065                 echo "done"
7066                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7067                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7068                         error "cannot getstripe for 1GB file"
7069                 [ $stripe_count -eq 2 ] ||
7070                         error "unexpected stripe count $stripe_count != 2"
7071                 echo "done"
7072         fi
7073
7074         # Test 3: File is too large to fit within the available space on
7075         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7076         if [ $OSTCOUNT -ge 3 ]; then
7077                 # The required available space is calculated as
7078                 # file size (1GB + 3KB) / OST count (3).
7079                 local kb_per_ost=349526
7080
7081                 echo -n "Migrating 1GB file with limit..."
7082                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7083                         error "cannot migrate 1GB file with limit"
7084                 echo "done"
7085
7086                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7087                 echo -n "Verifying 1GB autostripe count with limited space..."
7088                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7089                         error "unexpected stripe count $stripe_count (min 3)"
7090                 echo "done"
7091         fi
7092
7093         # clean up
7094         rm -rf $dir
7095 }
7096 run_test 56xc "lfs migration autostripe"
7097
7098 test_56xd() {
7099         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7100
7101         local dir=$DIR/$tdir
7102         local f_mgrt=$dir/$tfile.mgrt
7103         local f_yaml=$dir/$tfile.yaml
7104         local f_copy=$dir/$tfile.copy
7105         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7106         local layout_copy="-c 2 -S 2M -i 1"
7107         local yamlfile=$dir/yamlfile
7108         local layout_before;
7109         local layout_after;
7110
7111         test_mkdir "$dir" || error "cannot create dir $dir"
7112         $LFS setstripe $layout_yaml $f_yaml ||
7113                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7114         $LFS getstripe --yaml $f_yaml > $yamlfile
7115         $LFS setstripe $layout_copy $f_copy ||
7116                 error "cannot setstripe $f_copy with layout $layout_copy"
7117         touch $f_mgrt
7118         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7119
7120         # 1. test option --yaml
7121         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7122                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7123         layout_before=$(get_layout_param $f_yaml)
7124         layout_after=$(get_layout_param $f_mgrt)
7125         [ "$layout_after" == "$layout_before" ] ||
7126                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7127
7128         # 2. test option --copy
7129         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7130                 error "cannot migrate $f_mgrt with --copy $f_copy"
7131         layout_before=$(get_layout_param $f_copy)
7132         layout_after=$(get_layout_param $f_mgrt)
7133         [ "$layout_after" == "$layout_before" ] ||
7134                 error "lfs_migrate --copy: $layout_after != $layout_before"
7135 }
7136 run_test 56xd "check lfs_migrate --yaml and --copy support"
7137
7138 test_56xe() {
7139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7140
7141         local dir=$DIR/$tdir
7142         local f_comp=$dir/$tfile
7143         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7144         local layout_before=""
7145         local layout_after=""
7146
7147         test_mkdir "$dir" || error "cannot create dir $dir"
7148         $LFS setstripe $layout $f_comp ||
7149                 error "cannot setstripe $f_comp with layout $layout"
7150         layout_before=$(get_layout_param $f_comp)
7151         dd if=/dev/zero of=$f_comp bs=1M count=4
7152
7153         # 1. migrate a comp layout file by lfs_migrate
7154         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7155         layout_after=$(get_layout_param $f_comp)
7156         [ "$layout_before" == "$layout_after" ] ||
7157                 error "lfs_migrate: $layout_before != $layout_after"
7158
7159         # 2. migrate a comp layout file by lfs migrate
7160         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7161         layout_after=$(get_layout_param $f_comp)
7162         [ "$layout_before" == "$layout_after" ] ||
7163                 error "lfs migrate: $layout_before != $layout_after"
7164 }
7165 run_test 56xe "migrate a composite layout file"
7166
7167 test_56xf() {
7168         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7169
7170         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7171                 skip "Need server version at least 2.13.53"
7172
7173         local dir=$DIR/$tdir
7174         local f_comp=$dir/$tfile
7175         local layout="-E 1M -c1 -E -1 -c2"
7176         local fid_before=""
7177         local fid_after=""
7178
7179         test_mkdir "$dir" || error "cannot create dir $dir"
7180         $LFS setstripe $layout $f_comp ||
7181                 error "cannot setstripe $f_comp with layout $layout"
7182         fid_before=$($LFS getstripe --fid $f_comp)
7183         dd if=/dev/zero of=$f_comp bs=1M count=4
7184
7185         # 1. migrate a comp layout file to a comp layout
7186         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7187         fid_after=$($LFS getstripe --fid $f_comp)
7188         [ "$fid_before" == "$fid_after" ] ||
7189                 error "comp-to-comp migrate: $fid_before != $fid_after"
7190
7191         # 2. migrate a comp layout file to a plain layout
7192         $LFS migrate -c2 $f_comp ||
7193                 error "cannot migrate $f_comp by lfs migrate"
7194         fid_after=$($LFS getstripe --fid $f_comp)
7195         [ "$fid_before" == "$fid_after" ] ||
7196                 error "comp-to-plain migrate: $fid_before != $fid_after"
7197
7198         # 3. migrate a plain layout file to a comp layout
7199         $LFS migrate $layout $f_comp ||
7200                 error "cannot migrate $f_comp by lfs migrate"
7201         fid_after=$($LFS getstripe --fid $f_comp)
7202         [ "$fid_before" == "$fid_after" ] ||
7203                 error "plain-to-comp migrate: $fid_before != $fid_after"
7204 }
7205 run_test 56xf "FID is not lost during migration of a composite layout file"
7206
7207 test_56y() {
7208         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7209                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7210
7211         local res=""
7212         local dir=$DIR/$tdir
7213         local f1=$dir/file1
7214         local f2=$dir/file2
7215
7216         test_mkdir -p $dir || error "creating dir $dir"
7217         touch $f1 || error "creating std file $f1"
7218         $MULTIOP $f2 H2c || error "creating released file $f2"
7219
7220         # a directory can be raid0, so ask only for files
7221         res=$($LFS find $dir -L raid0 -type f | wc -l)
7222         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7223
7224         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7225         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7226
7227         # only files can be released, so no need to force file search
7228         res=$($LFS find $dir -L released)
7229         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7230
7231         res=$($LFS find $dir -type f \! -L released)
7232         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7233 }
7234 run_test 56y "lfs find -L raid0|released"
7235
7236 test_56z() { # LU-4824
7237         # This checks to make sure 'lfs find' continues after errors
7238         # There are two classes of errors that should be caught:
7239         # - If multiple paths are provided, all should be searched even if one
7240         #   errors out
7241         # - If errors are encountered during the search, it should not terminate
7242         #   early
7243         local dir=$DIR/$tdir
7244         local i
7245
7246         test_mkdir $dir
7247         for i in d{0..9}; do
7248                 test_mkdir $dir/$i
7249                 touch $dir/$i/$tfile
7250         done
7251         $LFS find $DIR/non_existent_dir $dir &&
7252                 error "$LFS find did not return an error"
7253         # Make a directory unsearchable. This should NOT be the last entry in
7254         # directory order.  Arbitrarily pick the 6th entry
7255         chmod 700 $($LFS find $dir -type d | sed '6!d')
7256
7257         $RUNAS $LFS find $DIR/non_existent $dir
7258         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7259
7260         # The user should be able to see 10 directories and 9 files
7261         (( count == 19 )) ||
7262                 error "$LFS find found $count != 19 entries after error"
7263 }
7264 run_test 56z "lfs find should continue after an error"
7265
7266 test_56aa() { # LU-5937
7267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7268
7269         local dir=$DIR/$tdir
7270
7271         mkdir $dir
7272         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7273
7274         createmany -o $dir/striped_dir/${tfile}- 1024
7275         local dirs=$($LFS find --size +8k $dir/)
7276
7277         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7278 }
7279 run_test 56aa "lfs find --size under striped dir"
7280
7281 test_56ab() { # LU-10705
7282         test_mkdir $DIR/$tdir
7283         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7284         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7285         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7286         # Flush writes to ensure valid blocks.  Need to be more thorough for
7287         # ZFS, since blocks are not allocated/returned to client immediately.
7288         sync_all_data
7289         wait_zfs_commit ost1 2
7290         cancel_lru_locks osc
7291         ls -ls $DIR/$tdir
7292
7293         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7294
7295         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7296
7297         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7298         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7299
7300         rm -f $DIR/$tdir/$tfile.[123]
7301 }
7302 run_test 56ab "lfs find --blocks"
7303
7304 test_56ba() {
7305         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7306                 skip "Need MDS version at least 2.10.50"
7307
7308         # Create composite files with one component
7309         local dir=$DIR/$tdir
7310
7311         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7312         # Create composite files with three components
7313         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7314         # Create non-composite files
7315         createmany -o $dir/${tfile}- 10
7316
7317         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7318
7319         [[ $nfiles == 10 ]] ||
7320                 error "lfs find -E 1M found $nfiles != 10 files"
7321
7322         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7323         [[ $nfiles == 25 ]] ||
7324                 error "lfs find ! -E 1M found $nfiles != 25 files"
7325
7326         # All files have a component that starts at 0
7327         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7328         [[ $nfiles == 35 ]] ||
7329                 error "lfs find --component-start 0 - $nfiles != 35 files"
7330
7331         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7332         [[ $nfiles == 15 ]] ||
7333                 error "lfs find --component-start 2M - $nfiles != 15 files"
7334
7335         # All files created here have a componenet that does not starts at 2M
7336         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7337         [[ $nfiles == 35 ]] ||
7338                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7339
7340         # Find files with a specified number of components
7341         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7342         [[ $nfiles == 15 ]] ||
7343                 error "lfs find --component-count 3 - $nfiles != 15 files"
7344
7345         # Remember non-composite files have a component count of zero
7346         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7347         [[ $nfiles == 10 ]] ||
7348                 error "lfs find --component-count 0 - $nfiles != 10 files"
7349
7350         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7351         [[ $nfiles == 20 ]] ||
7352                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7353
7354         # All files have a flag called "init"
7355         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7356         [[ $nfiles == 35 ]] ||
7357                 error "lfs find --component-flags init - $nfiles != 35 files"
7358
7359         # Multi-component files will have a component not initialized
7360         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7361         [[ $nfiles == 15 ]] ||
7362                 error "lfs find !--component-flags init - $nfiles != 15 files"
7363
7364         rm -rf $dir
7365
7366 }
7367 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7368
7369 test_56ca() {
7370         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7371                 skip "Need MDS version at least 2.10.57"
7372
7373         local td=$DIR/$tdir
7374         local tf=$td/$tfile
7375         local dir
7376         local nfiles
7377         local cmd
7378         local i
7379         local j
7380
7381         # create mirrored directories and mirrored files
7382         mkdir $td || error "mkdir $td failed"
7383         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7384         createmany -o $tf- 10 || error "create $tf- failed"
7385
7386         for i in $(seq 2); do
7387                 dir=$td/dir$i
7388                 mkdir $dir || error "mkdir $dir failed"
7389                 $LFS mirror create -N$((3 + i)) $dir ||
7390                         error "create mirrored dir $dir failed"
7391                 createmany -o $dir/$tfile- 10 ||
7392                         error "create $dir/$tfile- failed"
7393         done
7394
7395         # change the states of some mirrored files
7396         echo foo > $tf-6
7397         for i in $(seq 2); do
7398                 dir=$td/dir$i
7399                 for j in $(seq 4 9); do
7400                         echo foo > $dir/$tfile-$j
7401                 done
7402         done
7403
7404         # find mirrored files with specific mirror count
7405         cmd="$LFS find --mirror-count 3 --type f $td"
7406         nfiles=$($cmd | wc -l)
7407         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7408
7409         cmd="$LFS find ! --mirror-count 3 --type f $td"
7410         nfiles=$($cmd | wc -l)
7411         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7412
7413         cmd="$LFS find --mirror-count +2 --type f $td"
7414         nfiles=$($cmd | wc -l)
7415         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7416
7417         cmd="$LFS find --mirror-count -6 --type f $td"
7418         nfiles=$($cmd | wc -l)
7419         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7420
7421         # find mirrored files with specific file state
7422         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7423         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7424
7425         cmd="$LFS find --mirror-state=ro --type f $td"
7426         nfiles=$($cmd | wc -l)
7427         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7428
7429         cmd="$LFS find ! --mirror-state=ro --type f $td"
7430         nfiles=$($cmd | wc -l)
7431         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7432
7433         cmd="$LFS find --mirror-state=wp --type f $td"
7434         nfiles=$($cmd | wc -l)
7435         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7436
7437         cmd="$LFS find ! --mirror-state=sp --type f $td"
7438         nfiles=$($cmd | wc -l)
7439         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7440 }
7441 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7442
7443 test_57a() {
7444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7445         # note test will not do anything if MDS is not local
7446         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7447                 skip_env "ldiskfs only test"
7448         fi
7449         remote_mds_nodsh && skip "remote MDS with nodsh"
7450
7451         local MNTDEV="osd*.*MDT*.mntdev"
7452         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7453         [ -z "$DEV" ] && error "can't access $MNTDEV"
7454         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7455                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7456                         error "can't access $DEV"
7457                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7458                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7459                 rm $TMP/t57a.dump
7460         done
7461 }
7462 run_test 57a "verify MDS filesystem created with large inodes =="
7463
7464 test_57b() {
7465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7466         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7467                 skip_env "ldiskfs only test"
7468         fi
7469         remote_mds_nodsh && skip "remote MDS with nodsh"
7470
7471         local dir=$DIR/$tdir
7472         local filecount=100
7473         local file1=$dir/f1
7474         local fileN=$dir/f$filecount
7475
7476         rm -rf $dir || error "removing $dir"
7477         test_mkdir -c1 $dir
7478         local mdtidx=$($LFS getstripe -m $dir)
7479         local mdtname=MDT$(printf %04x $mdtidx)
7480         local facet=mds$((mdtidx + 1))
7481
7482         echo "mcreating $filecount files"
7483         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7484
7485         # verify that files do not have EAs yet
7486         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7487                 error "$file1 has an EA"
7488         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7489                 error "$fileN has an EA"
7490
7491         sync
7492         sleep 1
7493         df $dir  #make sure we get new statfs data
7494         local mdsfree=$(do_facet $facet \
7495                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7496         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7497         local file
7498
7499         echo "opening files to create objects/EAs"
7500         for file in $(seq -f $dir/f%g 1 $filecount); do
7501                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7502                         error "opening $file"
7503         done
7504
7505         # verify that files have EAs now
7506         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7507         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7508
7509         sleep 1  #make sure we get new statfs data
7510         df $dir
7511         local mdsfree2=$(do_facet $facet \
7512                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7513         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7514
7515         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7516                 if [ "$mdsfree" != "$mdsfree2" ]; then
7517                         error "MDC before $mdcfree != after $mdcfree2"
7518                 else
7519                         echo "MDC before $mdcfree != after $mdcfree2"
7520                         echo "unable to confirm if MDS has large inodes"
7521                 fi
7522         fi
7523         rm -rf $dir
7524 }
7525 run_test 57b "default LOV EAs are stored inside large inodes ==="
7526
7527 test_58() {
7528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7529         [ -z "$(which wiretest 2>/dev/null)" ] &&
7530                         skip_env "could not find wiretest"
7531
7532         wiretest
7533 }
7534 run_test 58 "verify cross-platform wire constants =============="
7535
7536 test_59() {
7537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7538
7539         echo "touch 130 files"
7540         createmany -o $DIR/f59- 130
7541         echo "rm 130 files"
7542         unlinkmany $DIR/f59- 130
7543         sync
7544         # wait for commitment of removal
7545         wait_delete_completed
7546 }
7547 run_test 59 "verify cancellation of llog records async ========="
7548
7549 TEST60_HEAD="test_60 run $RANDOM"
7550 test_60a() {
7551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7552         remote_mgs_nodsh && skip "remote MGS with nodsh"
7553         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7554                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7555                         skip_env "missing subtest run-llog.sh"
7556
7557         log "$TEST60_HEAD - from kernel mode"
7558         do_facet mgs "$LCTL dk > /dev/null"
7559         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7560         do_facet mgs $LCTL dk > $TMP/$tfile
7561
7562         # LU-6388: test llog_reader
7563         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7564         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7565         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7566                         skip_env "missing llog_reader"
7567         local fstype=$(facet_fstype mgs)
7568         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7569                 skip_env "Only for ldiskfs or zfs type mgs"
7570
7571         local mntpt=$(facet_mntpt mgs)
7572         local mgsdev=$(mgsdevname 1)
7573         local fid_list
7574         local fid
7575         local rec_list
7576         local rec
7577         local rec_type
7578         local obj_file
7579         local path
7580         local seq
7581         local oid
7582         local pass=true
7583
7584         #get fid and record list
7585         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7586                 tail -n 4))
7587         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7588                 tail -n 4))
7589         #remount mgs as ldiskfs or zfs type
7590         stop mgs || error "stop mgs failed"
7591         mount_fstype mgs || error "remount mgs failed"
7592         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7593                 fid=${fid_list[i]}
7594                 rec=${rec_list[i]}
7595                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7596                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7597                 oid=$((16#$oid))
7598
7599                 case $fstype in
7600                         ldiskfs )
7601                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7602                         zfs )
7603                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7604                 esac
7605                 echo "obj_file is $obj_file"
7606                 do_facet mgs $llog_reader $obj_file
7607
7608                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7609                         awk '{ print $3 }' | sed -e "s/^type=//g")
7610                 if [ $rec_type != $rec ]; then
7611                         echo "FAILED test_60a wrong record type $rec_type," \
7612                               "should be $rec"
7613                         pass=false
7614                         break
7615                 fi
7616
7617                 #check obj path if record type is LLOG_LOGID_MAGIC
7618                 if [ "$rec" == "1064553b" ]; then
7619                         path=$(do_facet mgs $llog_reader $obj_file |
7620                                 grep "path=" | awk '{ print $NF }' |
7621                                 sed -e "s/^path=//g")
7622                         if [ $obj_file != $mntpt/$path ]; then
7623                                 echo "FAILED test_60a wrong obj path" \
7624                                       "$montpt/$path, should be $obj_file"
7625                                 pass=false
7626                                 break
7627                         fi
7628                 fi
7629         done
7630         rm -f $TMP/$tfile
7631         #restart mgs before "error", otherwise it will block the next test
7632         stop mgs || error "stop mgs failed"
7633         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7634         $pass || error "test failed, see FAILED test_60a messages for specifics"
7635 }
7636 run_test 60a "llog_test run from kernel module and test llog_reader"
7637
7638 test_60b() { # bug 6411
7639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7640
7641         dmesg > $DIR/$tfile
7642         LLOG_COUNT=$(do_facet mgs dmesg |
7643                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7644                           /llog_[a-z]*.c:[0-9]/ {
7645                                 if (marker)
7646                                         from_marker++
7647                                 from_begin++
7648                           }
7649                           END {
7650                                 if (marker)
7651                                         print from_marker
7652                                 else
7653                                         print from_begin
7654                           }")
7655
7656         [[ $LLOG_COUNT -gt 120 ]] &&
7657                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7658 }
7659 run_test 60b "limit repeated messages from CERROR/CWARN"
7660
7661 test_60c() {
7662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7663
7664         echo "create 5000 files"
7665         createmany -o $DIR/f60c- 5000
7666 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7667         lctl set_param fail_loc=0x80000137
7668         unlinkmany $DIR/f60c- 5000
7669         lctl set_param fail_loc=0
7670 }
7671 run_test 60c "unlink file when mds full"
7672
7673 test_60d() {
7674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7675
7676         SAVEPRINTK=$(lctl get_param -n printk)
7677         # verify "lctl mark" is even working"
7678         MESSAGE="test message ID $RANDOM $$"
7679         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7680         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7681
7682         lctl set_param printk=0 || error "set lnet.printk failed"
7683         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7684         MESSAGE="new test message ID $RANDOM $$"
7685         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7686         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7687         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7688
7689         lctl set_param -n printk="$SAVEPRINTK"
7690 }
7691 run_test 60d "test printk console message masking"
7692
7693 test_60e() {
7694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7695         remote_mds_nodsh && skip "remote MDS with nodsh"
7696
7697         touch $DIR/$tfile
7698 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7699         do_facet mds1 lctl set_param fail_loc=0x15b
7700         rm $DIR/$tfile
7701 }
7702 run_test 60e "no space while new llog is being created"
7703
7704 test_60g() {
7705         local pid
7706         local i
7707
7708         test_mkdir -c $MDSCOUNT $DIR/$tdir
7709
7710         (
7711                 local index=0
7712                 while true; do
7713                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7714                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7715                                 2>/dev/null
7716                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7717                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7718                         index=$((index + 1))
7719                 done
7720         ) &
7721
7722         pid=$!
7723
7724         for i in {0..100}; do
7725                 # define OBD_FAIL_OSD_TXN_START    0x19a
7726                 local index=$((i % MDSCOUNT + 1))
7727
7728                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7729                         > /dev/null
7730                 sleep 0.01
7731         done
7732
7733         kill -9 $pid
7734
7735         for i in $(seq $MDSCOUNT); do
7736                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7737         done
7738
7739         mkdir $DIR/$tdir/new || error "mkdir failed"
7740         rmdir $DIR/$tdir/new || error "rmdir failed"
7741
7742         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7743                 -t namespace
7744         for i in $(seq $MDSCOUNT); do
7745                 wait_update_facet mds$i "$LCTL get_param -n \
7746                         mdd.$(facet_svc mds$i).lfsck_namespace |
7747                         awk '/^status/ { print \\\$2 }'" "completed"
7748         done
7749
7750         ls -R $DIR/$tdir || error "ls failed"
7751         rm -rf $DIR/$tdir || error "rmdir failed"
7752 }
7753 run_test 60g "transaction abort won't cause MDT hung"
7754
7755 test_60h() {
7756         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7757                 skip "Need MDS version at least 2.12.52"
7758         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7759
7760         local f
7761
7762         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7763         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7764         for fail_loc in 0x80000188 0x80000189; do
7765                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7766                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7767                         error "mkdir $dir-$fail_loc failed"
7768                 for i in {0..10}; do
7769                         # create may fail on missing stripe
7770                         echo $i > $DIR/$tdir-$fail_loc/$i
7771                 done
7772                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7773                         error "getdirstripe $tdir-$fail_loc failed"
7774                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7775                         error "migrate $tdir-$fail_loc failed"
7776                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7777                         error "getdirstripe $tdir-$fail_loc failed"
7778                 pushd $DIR/$tdir-$fail_loc
7779                 for f in *; do
7780                         echo $f | cmp $f - || error "$f data mismatch"
7781                 done
7782                 popd
7783                 rm -rf $DIR/$tdir-$fail_loc
7784         done
7785 }
7786 run_test 60h "striped directory with missing stripes can be accessed"
7787
7788 test_61a() {
7789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7790
7791         f="$DIR/f61"
7792         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7793         cancel_lru_locks osc
7794         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7795         sync
7796 }
7797 run_test 61a "mmap() writes don't make sync hang ================"
7798
7799 test_61b() {
7800         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7801 }
7802 run_test 61b "mmap() of unstriped file is successful"
7803
7804 # bug 2330 - insufficient obd_match error checking causes LBUG
7805 test_62() {
7806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7807
7808         f="$DIR/f62"
7809         echo foo > $f
7810         cancel_lru_locks osc
7811         lctl set_param fail_loc=0x405
7812         cat $f && error "cat succeeded, expect -EIO"
7813         lctl set_param fail_loc=0
7814 }
7815 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7816 # match every page all of the time.
7817 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7818
7819 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7820 # Though this test is irrelevant anymore, it helped to reveal some
7821 # other grant bugs (LU-4482), let's keep it.
7822 test_63a() {   # was test_63
7823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7824
7825         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7826
7827         for i in `seq 10` ; do
7828                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7829                 sleep 5
7830                 kill $!
7831                 sleep 1
7832         done
7833
7834         rm -f $DIR/f63 || true
7835 }
7836 run_test 63a "Verify oig_wait interruption does not crash ======="
7837
7838 # bug 2248 - async write errors didn't return to application on sync
7839 # bug 3677 - async write errors left page locked
7840 test_63b() {
7841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7842
7843         debugsave
7844         lctl set_param debug=-1
7845
7846         # ensure we have a grant to do async writes
7847         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7848         rm $DIR/$tfile
7849
7850         sync    # sync lest earlier test intercept the fail_loc
7851
7852         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7853         lctl set_param fail_loc=0x80000406
7854         $MULTIOP $DIR/$tfile Owy && \
7855                 error "sync didn't return ENOMEM"
7856         sync; sleep 2; sync     # do a real sync this time to flush page
7857         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7858                 error "locked page left in cache after async error" || true
7859         debugrestore
7860 }
7861 run_test 63b "async write errors should be returned to fsync ==="
7862
7863 test_64a () {
7864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7865
7866         lfs df $DIR
7867         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7868 }
7869 run_test 64a "verify filter grant calculations (in kernel) ====="
7870
7871 test_64b () {
7872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7873
7874         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7875 }
7876 run_test 64b "check out-of-space detection on client"
7877
7878 test_64c() {
7879         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7880 }
7881 run_test 64c "verify grant shrink"
7882
7883 import_param() {
7884         local tgt=$1
7885         local param=$2
7886
7887         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7888 }
7889
7890 # this does exactly what osc_request.c:osc_announce_cached() does in
7891 # order to calculate max amount of grants to ask from server
7892 want_grant() {
7893         local tgt=$1
7894
7895         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7896         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7897
7898         ((rpc_in_flight++));
7899         nrpages=$((nrpages * rpc_in_flight))
7900
7901         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7902
7903         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7904
7905         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7906         local undirty=$((nrpages * PAGE_SIZE))
7907
7908         local max_extent_pages
7909         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7910         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7911         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7912         local grant_extent_tax
7913         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7914
7915         undirty=$((undirty + nrextents * grant_extent_tax))
7916
7917         echo $undirty
7918 }
7919
7920 # this is size of unit for grant allocation. It should be equal to
7921 # what tgt_grant.c:tgt_grant_chunk() calculates
7922 grant_chunk() {
7923         local tgt=$1
7924         local max_brw_size
7925         local grant_extent_tax
7926
7927         max_brw_size=$(import_param $tgt max_brw_size)
7928
7929         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7930
7931         echo $(((max_brw_size + grant_extent_tax) * 2))
7932 }
7933
7934 test_64d() {
7935         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7936                 skip "OST < 2.10.55 doesn't limit grants enough"
7937
7938         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7939
7940         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7941                 skip "no grant_param connect flag"
7942
7943         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7944
7945         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7946         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7947
7948
7949         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7950         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7951
7952         $LFS setstripe $DIR/$tfile -i 0 -c 1
7953         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7954         ddpid=$!
7955
7956         while kill -0 $ddpid; do
7957                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7958
7959                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7960                         kill $ddpid
7961                         error "cur_grant $cur_grant > $max_cur_granted"
7962                 fi
7963
7964                 sleep 1
7965         done
7966 }
7967 run_test 64d "check grant limit exceed"
7968
7969 check_grants() {
7970         local tgt=$1
7971         local expected=$2
7972         local msg=$3
7973         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7974
7975         ((cur_grants == expected)) ||
7976                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7977 }
7978
7979 round_up_p2() {
7980         echo $((($1 + $2 - 1) & ~($2 - 1)))
7981 }
7982
7983 test_64e() {
7984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7985         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7986                 skip "Need OSS version at least 2.11.56"
7987
7988         # Remount client to reset grant
7989         remount_client $MOUNT || error "failed to remount client"
7990         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7991
7992         local init_grants=$(import_param $osc_tgt initial_grant)
7993
7994         check_grants $osc_tgt $init_grants "init grants"
7995
7996         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7997         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7998         local gbs=$(import_param $osc_tgt grant_block_size)
7999
8000         # write random number of bytes from max_brw_size / 4 to max_brw_size
8001         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8002         # align for direct io
8003         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8004         # round to grant consumption unit
8005         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8006
8007         local grants=$((wb_round_up + extent_tax))
8008
8009         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8010
8011         # define OBD_FAIL_TGT_NO_GRANT 0x725
8012         # make the server not grant more back
8013         do_facet ost1 $LCTL set_param fail_loc=0x725
8014         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8015
8016         do_facet ost1 $LCTL set_param fail_loc=0
8017
8018         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8019
8020         rm -f $DIR/$tfile || error "rm failed"
8021
8022         # Remount client to reset grant
8023         remount_client $MOUNT || error "failed to remount client"
8024         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8025
8026         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8027
8028         # define OBD_FAIL_TGT_NO_GRANT 0x725
8029         # make the server not grant more back
8030         do_facet ost1 $LCTL set_param fail_loc=0x725
8031         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8032         do_facet ost1 $LCTL set_param fail_loc=0
8033
8034         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8035 }
8036 run_test 64e "check grant consumption (no grant allocation)"
8037
8038 test_64f() {
8039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8040
8041         # Remount client to reset grant
8042         remount_client $MOUNT || error "failed to remount client"
8043         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8044
8045         local init_grants=$(import_param $osc_tgt initial_grant)
8046         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8047         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8048         local gbs=$(import_param $osc_tgt grant_block_size)
8049         local chunk=$(grant_chunk $osc_tgt)
8050
8051         # write random number of bytes from max_brw_size / 4 to max_brw_size
8052         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8053         # align for direct io
8054         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8055         # round to grant consumption unit
8056         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8057
8058         local grants=$((wb_round_up + extent_tax))
8059
8060         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8061         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8062                 error "error writing to $DIR/$tfile"
8063
8064         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8065                 "direct io with grant allocation"
8066
8067         rm -f $DIR/$tfile || error "rm failed"
8068
8069         # Remount client to reset grant
8070         remount_client $MOUNT || error "failed to remount client"
8071         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8072
8073         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8074
8075         local cmd="oO_WRONLY:w${write_bytes}_yc"
8076
8077         $MULTIOP $DIR/$tfile $cmd &
8078         MULTIPID=$!
8079         sleep 1
8080
8081         check_grants $osc_tgt $((init_grants - grants)) \
8082                 "buffered io, not write rpc"
8083
8084         kill -USR1 $MULTIPID
8085         wait
8086
8087         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8088                 "buffered io, one RPC"
8089 }
8090 run_test 64f "check grant consumption (with grant allocation)"
8091
8092 # bug 1414 - set/get directories' stripe info
8093 test_65a() {
8094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8095
8096         test_mkdir $DIR/$tdir
8097         touch $DIR/$tdir/f1
8098         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8099 }
8100 run_test 65a "directory with no stripe info"
8101
8102 test_65b() {
8103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8104
8105         test_mkdir $DIR/$tdir
8106         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8107
8108         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8109                                                 error "setstripe"
8110         touch $DIR/$tdir/f2
8111         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8112 }
8113 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8114
8115 test_65c() {
8116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8117         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8118
8119         test_mkdir $DIR/$tdir
8120         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8121
8122         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8123                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8124         touch $DIR/$tdir/f3
8125         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8126 }
8127 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8128
8129 test_65d() {
8130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8131
8132         test_mkdir $DIR/$tdir
8133         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8134         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8135
8136         if [[ $STRIPECOUNT -le 0 ]]; then
8137                 sc=1
8138         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8139                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8140                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8141         else
8142                 sc=$(($STRIPECOUNT - 1))
8143         fi
8144         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8145         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8146         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8147                 error "lverify failed"
8148 }
8149 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8150
8151 test_65e() {
8152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8153
8154         test_mkdir $DIR/$tdir
8155
8156         $LFS setstripe $DIR/$tdir || error "setstripe"
8157         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8158                                         error "no stripe info failed"
8159         touch $DIR/$tdir/f6
8160         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8161 }
8162 run_test 65e "directory setstripe defaults"
8163
8164 test_65f() {
8165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8166
8167         test_mkdir $DIR/${tdir}f
8168         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8169                 error "setstripe succeeded" || true
8170 }
8171 run_test 65f "dir setstripe permission (should return error) ==="
8172
8173 test_65g() {
8174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8175
8176         test_mkdir $DIR/$tdir
8177         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8178
8179         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8180                 error "setstripe -S failed"
8181         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8182         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8183                 error "delete default stripe failed"
8184 }
8185 run_test 65g "directory setstripe -d"
8186
8187 test_65h() {
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189
8190         test_mkdir $DIR/$tdir
8191         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8192
8193         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8194                 error "setstripe -S failed"
8195         test_mkdir $DIR/$tdir/dd1
8196         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8197                 error "stripe info inherit failed"
8198 }
8199 run_test 65h "directory stripe info inherit ===================="
8200
8201 test_65i() {
8202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8203
8204         save_layout_restore_at_exit $MOUNT
8205
8206         # bug6367: set non-default striping on root directory
8207         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8208
8209         # bug12836: getstripe on -1 default directory striping
8210         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8211
8212         # bug12836: getstripe -v on -1 default directory striping
8213         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8214
8215         # bug12836: new find on -1 default directory striping
8216         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8217 }
8218 run_test 65i "various tests to set root directory striping"
8219
8220 test_65j() { # bug6367
8221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8222
8223         sync; sleep 1
8224
8225         # if we aren't already remounting for each test, do so for this test
8226         if [ "$I_MOUNTED" = "yes" ]; then
8227                 cleanup || error "failed to unmount"
8228                 setup
8229         fi
8230
8231         save_layout_restore_at_exit $MOUNT
8232
8233         $LFS setstripe -d $MOUNT || error "setstripe failed"
8234 }
8235 run_test 65j "set default striping on root directory (bug 6367)="
8236
8237 cleanup_65k() {
8238         rm -rf $DIR/$tdir
8239         wait_delete_completed
8240         do_facet $SINGLEMDS "lctl set_param -n \
8241                 osp.$ost*MDT0000.max_create_count=$max_count"
8242         do_facet $SINGLEMDS "lctl set_param -n \
8243                 osp.$ost*MDT0000.create_count=$count"
8244         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8245         echo $INACTIVE_OSC "is Activate"
8246
8247         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8248 }
8249
8250 test_65k() { # bug11679
8251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8252         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8253         remote_mds_nodsh && skip "remote MDS with nodsh"
8254
8255         local disable_precreate=true
8256         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8257                 disable_precreate=false
8258
8259         echo "Check OST status: "
8260         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8261                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8262
8263         for OSC in $MDS_OSCS; do
8264                 echo $OSC "is active"
8265                 do_facet $SINGLEMDS lctl --device %$OSC activate
8266         done
8267
8268         for INACTIVE_OSC in $MDS_OSCS; do
8269                 local ost=$(osc_to_ost $INACTIVE_OSC)
8270                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8271                                lov.*md*.target_obd |
8272                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8273
8274                 mkdir -p $DIR/$tdir
8275                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8276                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8277
8278                 echo "Deactivate: " $INACTIVE_OSC
8279                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8280
8281                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8282                               osp.$ost*MDT0000.create_count")
8283                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8284                                   osp.$ost*MDT0000.max_create_count")
8285                 $disable_precreate &&
8286                         do_facet $SINGLEMDS "lctl set_param -n \
8287                                 osp.$ost*MDT0000.max_create_count=0"
8288
8289                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8290                         [ -f $DIR/$tdir/$idx ] && continue
8291                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8292                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8293                                 { cleanup_65k;
8294                                   error "setstripe $idx should succeed"; }
8295                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8296                 done
8297                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8298                 rmdir $DIR/$tdir
8299
8300                 do_facet $SINGLEMDS "lctl set_param -n \
8301                         osp.$ost*MDT0000.max_create_count=$max_count"
8302                 do_facet $SINGLEMDS "lctl set_param -n \
8303                         osp.$ost*MDT0000.create_count=$count"
8304                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8305                 echo $INACTIVE_OSC "is Activate"
8306
8307                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8308         done
8309 }
8310 run_test 65k "validate manual striping works properly with deactivated OSCs"
8311
8312 test_65l() { # bug 12836
8313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8314
8315         test_mkdir -p $DIR/$tdir/test_dir
8316         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8317         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8318 }
8319 run_test 65l "lfs find on -1 stripe dir ========================"
8320
8321 test_65m() {
8322         local layout=$(save_layout $MOUNT)
8323         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8324                 restore_layout $MOUNT $layout
8325                 error "setstripe should fail by non-root users"
8326         }
8327         true
8328 }
8329 run_test 65m "normal user can't set filesystem default stripe"
8330
8331 test_65n() {
8332         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8333         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8334                 skip "Need MDS version at least 2.12.50"
8335         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8336
8337         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8338         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8339         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8340
8341         local root_layout=$(save_layout $MOUNT)
8342         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8343
8344         # new subdirectory under root directory should not inherit
8345         # the default layout from root
8346         local dir1=$MOUNT/$tdir-1
8347         mkdir $dir1 || error "mkdir $dir1 failed"
8348         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8349                 error "$dir1 shouldn't have LOV EA"
8350
8351         # delete the default layout on root directory
8352         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8353
8354         local dir2=$MOUNT/$tdir-2
8355         mkdir $dir2 || error "mkdir $dir2 failed"
8356         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8357                 error "$dir2 shouldn't have LOV EA"
8358
8359         # set a new striping pattern on root directory
8360         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8361         local new_def_stripe_size=$((def_stripe_size * 2))
8362         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8363                 error "set stripe size on $MOUNT failed"
8364
8365         # new file created in $dir2 should inherit the new stripe size from
8366         # the filesystem default
8367         local file2=$dir2/$tfile-2
8368         touch $file2 || error "touch $file2 failed"
8369
8370         local file2_stripe_size=$($LFS getstripe -S $file2)
8371         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8372                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8373
8374         local dir3=$MOUNT/$tdir-3
8375         mkdir $dir3 || error "mkdir $dir3 failed"
8376         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8377         # the root layout, which is the actual default layout that will be used
8378         # when new files are created in $dir3.
8379         local dir3_layout=$(get_layout_param $dir3)
8380         local root_dir_layout=$(get_layout_param $MOUNT)
8381         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8382                 error "$dir3 should show the default layout from $MOUNT"
8383
8384         # set OST pool on root directory
8385         local pool=$TESTNAME
8386         pool_add $pool || error "add $pool failed"
8387         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8388                 error "add targets to $pool failed"
8389
8390         $LFS setstripe -p $pool $MOUNT ||
8391                 error "set OST pool on $MOUNT failed"
8392
8393         # new file created in $dir3 should inherit the pool from
8394         # the filesystem default
8395         local file3=$dir3/$tfile-3
8396         touch $file3 || error "touch $file3 failed"
8397
8398         local file3_pool=$($LFS getstripe -p $file3)
8399         [[ "$file3_pool" = "$pool" ]] ||
8400                 error "$file3 didn't inherit OST pool $pool"
8401
8402         local dir4=$MOUNT/$tdir-4
8403         mkdir $dir4 || error "mkdir $dir4 failed"
8404         local dir4_layout=$(get_layout_param $dir4)
8405         root_dir_layout=$(get_layout_param $MOUNT)
8406         echo "$LFS getstripe -d $dir4"
8407         $LFS getstripe -d $dir4
8408         echo "$LFS getstripe -d $MOUNT"
8409         $LFS getstripe -d $MOUNT
8410         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8411                 error "$dir4 should show the default layout from $MOUNT"
8412
8413         # new file created in $dir4 should inherit the pool from
8414         # the filesystem default
8415         local file4=$dir4/$tfile-4
8416         touch $file4 || error "touch $file4 failed"
8417
8418         local file4_pool=$($LFS getstripe -p $file4)
8419         [[ "$file4_pool" = "$pool" ]] ||
8420                 error "$file4 didn't inherit OST pool $pool"
8421
8422         # new subdirectory under non-root directory should inherit
8423         # the default layout from its parent directory
8424         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8425                 error "set directory layout on $dir4 failed"
8426
8427         local dir5=$dir4/$tdir-5
8428         mkdir $dir5 || error "mkdir $dir5 failed"
8429
8430         dir4_layout=$(get_layout_param $dir4)
8431         local dir5_layout=$(get_layout_param $dir5)
8432         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8433                 error "$dir5 should inherit the default layout from $dir4"
8434
8435         # though subdir under ROOT doesn't inherit default layout, but
8436         # its sub dir/file should be created with default layout.
8437         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8438         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8439                 skip "Need MDS version at least 2.12.59"
8440
8441         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8442         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8443         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8444
8445         if [ $default_lmv_hash == "none" ]; then
8446                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8447         else
8448                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8449                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8450         fi
8451
8452         $LFS setdirstripe -D -c 2 $MOUNT ||
8453                 error "setdirstripe -D -c 2 failed"
8454         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8455         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8456         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8457 }
8458 run_test 65n "don't inherit default layout from root for new subdirectories"
8459
8460 # bug 2543 - update blocks count on client
8461 test_66() {
8462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8463
8464         COUNT=${COUNT:-8}
8465         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8466         sync; sync_all_data; sync; sync_all_data
8467         cancel_lru_locks osc
8468         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8469         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8470 }
8471 run_test 66 "update inode blocks count on client ==============="
8472
8473 meminfo() {
8474         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8475 }
8476
8477 swap_used() {
8478         swapon -s | awk '($1 == "'$1'") { print $4 }'
8479 }
8480
8481 # bug5265, obdfilter oa2dentry return -ENOENT
8482 # #define OBD_FAIL_SRV_ENOENT 0x217
8483 test_69() {
8484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8485         remote_ost_nodsh && skip "remote OST with nodsh"
8486
8487         f="$DIR/$tfile"
8488         $LFS setstripe -c 1 -i 0 $f
8489
8490         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8491
8492         do_facet ost1 lctl set_param fail_loc=0x217
8493         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8494         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8495
8496         do_facet ost1 lctl set_param fail_loc=0
8497         $DIRECTIO write $f 0 2 || error "write error"
8498
8499         cancel_lru_locks osc
8500         $DIRECTIO read $f 0 1 || error "read error"
8501
8502         do_facet ost1 lctl set_param fail_loc=0x217
8503         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8504
8505         do_facet ost1 lctl set_param fail_loc=0
8506         rm -f $f
8507 }
8508 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8509
8510 test_71() {
8511         test_mkdir $DIR/$tdir
8512         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8513         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8514 }
8515 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8516
8517 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8519         [ "$RUNAS_ID" = "$UID" ] &&
8520                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8521         # Check that testing environment is properly set up. Skip if not
8522         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8523                 skip_env "User $RUNAS_ID does not exist - skipping"
8524
8525         touch $DIR/$tfile
8526         chmod 777 $DIR/$tfile
8527         chmod ug+s $DIR/$tfile
8528         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8529                 error "$RUNAS dd $DIR/$tfile failed"
8530         # See if we are still setuid/sgid
8531         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8532                 error "S/gid is not dropped on write"
8533         # Now test that MDS is updated too
8534         cancel_lru_locks mdc
8535         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8536                 error "S/gid is not dropped on MDS"
8537         rm -f $DIR/$tfile
8538 }
8539 run_test 72a "Test that remove suid works properly (bug5695) ===="
8540
8541 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8542         local perm
8543
8544         [ "$RUNAS_ID" = "$UID" ] &&
8545                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8546         [ "$RUNAS_ID" -eq 0 ] &&
8547                 skip_env "RUNAS_ID = 0 -- skipping"
8548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8549         # Check that testing environment is properly set up. Skip if not
8550         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8551                 skip_env "User $RUNAS_ID does not exist - skipping"
8552
8553         touch $DIR/${tfile}-f{g,u}
8554         test_mkdir $DIR/${tfile}-dg
8555         test_mkdir $DIR/${tfile}-du
8556         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8557         chmod g+s $DIR/${tfile}-{f,d}g
8558         chmod u+s $DIR/${tfile}-{f,d}u
8559         for perm in 777 2777 4777; do
8560                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8561                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8562                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8563                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8564         done
8565         true
8566 }
8567 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8568
8569 # bug 3462 - multiple simultaneous MDC requests
8570 test_73() {
8571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8572
8573         test_mkdir $DIR/d73-1
8574         test_mkdir $DIR/d73-2
8575         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8576         pid1=$!
8577
8578         lctl set_param fail_loc=0x80000129
8579         $MULTIOP $DIR/d73-1/f73-2 Oc &
8580         sleep 1
8581         lctl set_param fail_loc=0
8582
8583         $MULTIOP $DIR/d73-2/f73-3 Oc &
8584         pid3=$!
8585
8586         kill -USR1 $pid1
8587         wait $pid1 || return 1
8588
8589         sleep 25
8590
8591         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8592         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8593         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8594
8595         rm -rf $DIR/d73-*
8596 }
8597 run_test 73 "multiple MDC requests (should not deadlock)"
8598
8599 test_74a() { # bug 6149, 6184
8600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8601
8602         touch $DIR/f74a
8603         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8604         #
8605         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8606         # will spin in a tight reconnection loop
8607         $LCTL set_param fail_loc=0x8000030e
8608         # get any lock that won't be difficult - lookup works.
8609         ls $DIR/f74a
8610         $LCTL set_param fail_loc=0
8611         rm -f $DIR/f74a
8612         true
8613 }
8614 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8615
8616 test_74b() { # bug 13310
8617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8618
8619         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8620         #
8621         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8622         # will spin in a tight reconnection loop
8623         $LCTL set_param fail_loc=0x8000030e
8624         # get a "difficult" lock
8625         touch $DIR/f74b
8626         $LCTL set_param fail_loc=0
8627         rm -f $DIR/f74b
8628         true
8629 }
8630 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8631
8632 test_74c() {
8633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8634
8635         #define OBD_FAIL_LDLM_NEW_LOCK
8636         $LCTL set_param fail_loc=0x319
8637         touch $DIR/$tfile && error "touch successful"
8638         $LCTL set_param fail_loc=0
8639         true
8640 }
8641 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8642
8643 slab_lic=/sys/kernel/slab/lustre_inode_cache
8644 num_objects() {
8645         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8646         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8647                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8648 }
8649
8650 test_76a() { # Now for b=20433, added originally in b=1443
8651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8652
8653         cancel_lru_locks osc
8654         # there may be some slab objects cached per core
8655         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8656         local before=$(num_objects)
8657         local count=$((512 * cpus))
8658         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8659         local margin=$((count / 10))
8660         if [[ -f $slab_lic/aliases ]]; then
8661                 local aliases=$(cat $slab_lic/aliases)
8662                 (( aliases > 0 )) && margin=$((margin * aliases))
8663         fi
8664
8665         echo "before slab objects: $before"
8666         for i in $(seq $count); do
8667                 touch $DIR/$tfile
8668                 rm -f $DIR/$tfile
8669         done
8670         cancel_lru_locks osc
8671         local after=$(num_objects)
8672         echo "created: $count, after slab objects: $after"
8673         # shared slab counts are not very accurate, allow significant margin
8674         # the main goal is that the cache growth is not permanently > $count
8675         while (( after > before + margin )); do
8676                 sleep 1
8677                 after=$(num_objects)
8678                 wait=$((wait + 1))
8679                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8680                 if (( wait > 60 )); then
8681                         error "inode slab grew from $before+$margin to $after"
8682                 fi
8683         done
8684 }
8685 run_test 76a "confirm clients recycle inodes properly ===="
8686
8687 test_76b() {
8688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8689         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8690
8691         local count=512
8692         local before=$(num_objects)
8693
8694         for i in $(seq $count); do
8695                 mkdir $DIR/$tdir
8696                 rmdir $DIR/$tdir
8697         done
8698
8699         local after=$(num_objects)
8700         local wait=0
8701
8702         while (( after > before )); do
8703                 sleep 1
8704                 after=$(num_objects)
8705                 wait=$((wait + 1))
8706                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8707                 if (( wait > 60 )); then
8708                         error "inode slab grew from $before to $after"
8709                 fi
8710         done
8711
8712         echo "slab objects before: $before, after: $after"
8713 }
8714 run_test 76b "confirm clients recycle directory inodes properly ===="
8715
8716 export ORIG_CSUM=""
8717 set_checksums()
8718 {
8719         # Note: in sptlrpc modes which enable its own bulk checksum, the
8720         # original crc32_le bulk checksum will be automatically disabled,
8721         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8722         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8723         # In this case set_checksums() will not be no-op, because sptlrpc
8724         # bulk checksum will be enabled all through the test.
8725
8726         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8727         lctl set_param -n osc.*.checksums $1
8728         return 0
8729 }
8730
8731 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8732                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8733 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8734                              tr -d [] | head -n1)}
8735 set_checksum_type()
8736 {
8737         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8738         rc=$?
8739         log "set checksum type to $1, rc = $rc"
8740         return $rc
8741 }
8742
8743 get_osc_checksum_type()
8744 {
8745         # arugment 1: OST name, like OST0000
8746         ost=$1
8747         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8748                         sed 's/.*\[\(.*\)\].*/\1/g')
8749         rc=$?
8750         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8751         echo $checksum_type
8752 }
8753
8754 F77_TMP=$TMP/f77-temp
8755 F77SZ=8
8756 setup_f77() {
8757         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8758                 error "error writing to $F77_TMP"
8759 }
8760
8761 test_77a() { # bug 10889
8762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8763         $GSS && skip_env "could not run with gss"
8764
8765         [ ! -f $F77_TMP ] && setup_f77
8766         set_checksums 1
8767         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8768         set_checksums 0
8769         rm -f $DIR/$tfile
8770 }
8771 run_test 77a "normal checksum read/write operation"
8772
8773 test_77b() { # bug 10889
8774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8775         $GSS && skip_env "could not run with gss"
8776
8777         [ ! -f $F77_TMP ] && setup_f77
8778         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8779         $LCTL set_param fail_loc=0x80000409
8780         set_checksums 1
8781
8782         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8783                 error "dd error: $?"
8784         $LCTL set_param fail_loc=0
8785
8786         for algo in $CKSUM_TYPES; do
8787                 cancel_lru_locks osc
8788                 set_checksum_type $algo
8789                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8790                 $LCTL set_param fail_loc=0x80000408
8791                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8792                 $LCTL set_param fail_loc=0
8793         done
8794         set_checksums 0
8795         set_checksum_type $ORIG_CSUM_TYPE
8796         rm -f $DIR/$tfile
8797 }
8798 run_test 77b "checksum error on client write, read"
8799
8800 cleanup_77c() {
8801         trap 0
8802         set_checksums 0
8803         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8804         $check_ost &&
8805                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8806         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8807         $check_ost && [ -n "$ost_file_prefix" ] &&
8808                 do_facet ost1 rm -f ${ost_file_prefix}\*
8809 }
8810
8811 test_77c() {
8812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8813         $GSS && skip_env "could not run with gss"
8814         remote_ost_nodsh && skip "remote OST with nodsh"
8815
8816         local bad1
8817         local osc_file_prefix
8818         local osc_file
8819         local check_ost=false
8820         local ost_file_prefix
8821         local ost_file
8822         local orig_cksum
8823         local dump_cksum
8824         local fid
8825
8826         # ensure corruption will occur on first OSS/OST
8827         $LFS setstripe -i 0 $DIR/$tfile
8828
8829         [ ! -f $F77_TMP ] && setup_f77
8830         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8831                 error "dd write error: $?"
8832         fid=$($LFS path2fid $DIR/$tfile)
8833
8834         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8835         then
8836                 check_ost=true
8837                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8838                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8839         else
8840                 echo "OSS do not support bulk pages dump upon error"
8841         fi
8842
8843         osc_file_prefix=$($LCTL get_param -n debug_path)
8844         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8845
8846         trap cleanup_77c EXIT
8847
8848         set_checksums 1
8849         # enable bulk pages dump upon error on Client
8850         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8851         # enable bulk pages dump upon error on OSS
8852         $check_ost &&
8853                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8854
8855         # flush Client cache to allow next read to reach OSS
8856         cancel_lru_locks osc
8857
8858         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8859         $LCTL set_param fail_loc=0x80000408
8860         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8861         $LCTL set_param fail_loc=0
8862
8863         rm -f $DIR/$tfile
8864
8865         # check cksum dump on Client
8866         osc_file=$(ls ${osc_file_prefix}*)
8867         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8868         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8869         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8870         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8871         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8872                      cksum)
8873         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8874         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8875                 error "dump content does not match on Client"
8876
8877         $check_ost || skip "No need to check cksum dump on OSS"
8878
8879         # check cksum dump on OSS
8880         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8881         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8882         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8883         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8884         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8885                 error "dump content does not match on OSS"
8886
8887         cleanup_77c
8888 }
8889 run_test 77c "checksum error on client read with debug"
8890
8891 test_77d() { # bug 10889
8892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8893         $GSS && skip_env "could not run with gss"
8894
8895         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8896         $LCTL set_param fail_loc=0x80000409
8897         set_checksums 1
8898         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8899                 error "direct write: rc=$?"
8900         $LCTL set_param fail_loc=0
8901         set_checksums 0
8902
8903         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8904         $LCTL set_param fail_loc=0x80000408
8905         set_checksums 1
8906         cancel_lru_locks osc
8907         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8908                 error "direct read: rc=$?"
8909         $LCTL set_param fail_loc=0
8910         set_checksums 0
8911 }
8912 run_test 77d "checksum error on OST direct write, read"
8913
8914 test_77f() { # bug 10889
8915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8916         $GSS && skip_env "could not run with gss"
8917
8918         set_checksums 1
8919         for algo in $CKSUM_TYPES; do
8920                 cancel_lru_locks osc
8921                 set_checksum_type $algo
8922                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8923                 $LCTL set_param fail_loc=0x409
8924                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8925                         error "direct write succeeded"
8926                 $LCTL set_param fail_loc=0
8927         done
8928         set_checksum_type $ORIG_CSUM_TYPE
8929         set_checksums 0
8930 }
8931 run_test 77f "repeat checksum error on write (expect error)"
8932
8933 test_77g() { # bug 10889
8934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8935         $GSS && skip_env "could not run with gss"
8936         remote_ost_nodsh && skip "remote OST with nodsh"
8937
8938         [ ! -f $F77_TMP ] && setup_f77
8939
8940         local file=$DIR/$tfile
8941         stack_trap "rm -f $file" EXIT
8942
8943         $LFS setstripe -c 1 -i 0 $file
8944         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8945         do_facet ost1 lctl set_param fail_loc=0x8000021a
8946         set_checksums 1
8947         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8948                 error "write error: rc=$?"
8949         do_facet ost1 lctl set_param fail_loc=0
8950         set_checksums 0
8951
8952         cancel_lru_locks osc
8953         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8954         do_facet ost1 lctl set_param fail_loc=0x8000021b
8955         set_checksums 1
8956         cmp $F77_TMP $file || error "file compare failed"
8957         do_facet ost1 lctl set_param fail_loc=0
8958         set_checksums 0
8959 }
8960 run_test 77g "checksum error on OST write, read"
8961
8962 test_77k() { # LU-10906
8963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8964         $GSS && skip_env "could not run with gss"
8965
8966         local cksum_param="osc.$FSNAME*.checksums"
8967         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8968         local checksum
8969         local i
8970
8971         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8972         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8973         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8974
8975         for i in 0 1; do
8976                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8977                         error "failed to set checksum=$i on MGS"
8978                 wait_update $HOSTNAME "$get_checksum" $i
8979                 #remount
8980                 echo "remount client, checksum should be $i"
8981                 remount_client $MOUNT || error "failed to remount client"
8982                 checksum=$(eval $get_checksum)
8983                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8984         done
8985         # remove persistent param to avoid races with checksum mountopt below
8986         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8987                 error "failed to delete checksum on MGS"
8988
8989         for opt in "checksum" "nochecksum"; do
8990                 #remount with mount option
8991                 echo "remount client with option $opt, checksum should be $i"
8992                 umount_client $MOUNT || error "failed to umount client"
8993                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8994                         error "failed to mount client with option '$opt'"
8995                 checksum=$(eval $get_checksum)
8996                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8997                 i=$((i - 1))
8998         done
8999
9000         remount_client $MOUNT || error "failed to remount client"
9001 }
9002 run_test 77k "enable/disable checksum correctly"
9003
9004 test_77l() {
9005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9006         $GSS && skip_env "could not run with gss"
9007
9008         set_checksums 1
9009         stack_trap "set_checksums $ORIG_CSUM" EXIT
9010         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9011
9012         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9013
9014         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9015         for algo in $CKSUM_TYPES; do
9016                 set_checksum_type $algo || error "fail to set checksum type $algo"
9017                 osc_algo=$(get_osc_checksum_type OST0000)
9018                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9019
9020                 # no locks, no reqs to let the connection idle
9021                 cancel_lru_locks osc
9022                 lru_resize_disable osc
9023                 wait_osc_import_state client ost1 IDLE
9024
9025                 # ensure ost1 is connected
9026                 stat $DIR/$tfile >/dev/null || error "can't stat"
9027                 wait_osc_import_state client ost1 FULL
9028
9029                 osc_algo=$(get_osc_checksum_type OST0000)
9030                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9031         done
9032         return 0
9033 }
9034 run_test 77l "preferred checksum type is remembered after reconnected"
9035
9036 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9037 rm -f $F77_TMP
9038 unset F77_TMP
9039
9040 cleanup_test_78() {
9041         trap 0
9042         rm -f $DIR/$tfile
9043 }
9044
9045 test_78() { # bug 10901
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047         remote_ost || skip_env "local OST"
9048
9049         NSEQ=5
9050         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9051         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9052         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9053         echo "MemTotal: $MEMTOTAL"
9054
9055         # reserve 256MB of memory for the kernel and other running processes,
9056         # and then take 1/2 of the remaining memory for the read/write buffers.
9057         if [ $MEMTOTAL -gt 512 ] ;then
9058                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9059         else
9060                 # for those poor memory-starved high-end clusters...
9061                 MEMTOTAL=$((MEMTOTAL / 2))
9062         fi
9063         echo "Mem to use for directio: $MEMTOTAL"
9064
9065         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9066         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9067         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9068         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9069                 head -n1)
9070         echo "Smallest OST: $SMALLESTOST"
9071         [[ $SMALLESTOST -lt 10240 ]] &&
9072                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9073
9074         trap cleanup_test_78 EXIT
9075
9076         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9077                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9078
9079         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9080         echo "File size: $F78SIZE"
9081         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9082         for i in $(seq 1 $NSEQ); do
9083                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9084                 echo directIO rdwr round $i of $NSEQ
9085                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9086         done
9087
9088         cleanup_test_78
9089 }
9090 run_test 78 "handle large O_DIRECT writes correctly ============"
9091
9092 test_79() { # bug 12743
9093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9094
9095         wait_delete_completed
9096
9097         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9098         BKFREE=$(calc_osc_kbytes kbytesfree)
9099         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9100
9101         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9102         DFTOTAL=`echo $STRING | cut -d, -f1`
9103         DFUSED=`echo $STRING  | cut -d, -f2`
9104         DFAVAIL=`echo $STRING | cut -d, -f3`
9105         DFFREE=$(($DFTOTAL - $DFUSED))
9106
9107         ALLOWANCE=$((64 * $OSTCOUNT))
9108
9109         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9110            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9111                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9112         fi
9113         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9114            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9115                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9116         fi
9117         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9118            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9119                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9120         fi
9121 }
9122 run_test 79 "df report consistency check ======================="
9123
9124 test_80() { # bug 10718
9125         remote_ost_nodsh && skip "remote OST with nodsh"
9126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9127
9128         # relax strong synchronous semantics for slow backends like ZFS
9129         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9130                 local soc="obdfilter.*.sync_lock_cancel"
9131                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9132
9133                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9134                 if [ -z "$save" ]; then
9135                         soc="obdfilter.*.sync_on_lock_cancel"
9136                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9137                 fi
9138
9139                 if [ "$save" != "never" ]; then
9140                         local hosts=$(comma_list $(osts_nodes))
9141
9142                         do_nodes $hosts $LCTL set_param $soc=never
9143                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9144                 fi
9145         fi
9146
9147         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9148         sync; sleep 1; sync
9149         local before=$(date +%s)
9150         cancel_lru_locks osc
9151         local after=$(date +%s)
9152         local diff=$((after - before))
9153         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9154
9155         rm -f $DIR/$tfile
9156 }
9157 run_test 80 "Page eviction is equally fast at high offsets too"
9158
9159 test_81a() { # LU-456
9160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9161         remote_ost_nodsh && skip "remote OST with nodsh"
9162
9163         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9164         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9165         do_facet ost1 lctl set_param fail_loc=0x80000228
9166
9167         # write should trigger a retry and success
9168         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9169         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9170         RC=$?
9171         if [ $RC -ne 0 ] ; then
9172                 error "write should success, but failed for $RC"
9173         fi
9174 }
9175 run_test 81a "OST should retry write when get -ENOSPC ==============="
9176
9177 test_81b() { # LU-456
9178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9179         remote_ost_nodsh && skip "remote OST with nodsh"
9180
9181         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9182         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9183         do_facet ost1 lctl set_param fail_loc=0x228
9184
9185         # write should retry several times and return -ENOSPC finally
9186         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9187         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9188         RC=$?
9189         ENOSPC=28
9190         if [ $RC -ne $ENOSPC ] ; then
9191                 error "dd should fail for -ENOSPC, but succeed."
9192         fi
9193 }
9194 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9195
9196 test_99() {
9197         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9198
9199         test_mkdir $DIR/$tdir.cvsroot
9200         chown $RUNAS_ID $DIR/$tdir.cvsroot
9201
9202         cd $TMP
9203         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9204
9205         cd /etc/init.d
9206         # some versions of cvs import exit(1) when asked to import links or
9207         # files they can't read.  ignore those files.
9208         local toignore=$(find . -type l -printf '-I %f\n' -o \
9209                          ! -perm /4 -printf '-I %f\n')
9210         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9211                 $tdir.reposname vtag rtag
9212
9213         cd $DIR
9214         test_mkdir $DIR/$tdir.reposname
9215         chown $RUNAS_ID $DIR/$tdir.reposname
9216         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9217
9218         cd $DIR/$tdir.reposname
9219         $RUNAS touch foo99
9220         $RUNAS cvs add -m 'addmsg' foo99
9221         $RUNAS cvs update
9222         $RUNAS cvs commit -m 'nomsg' foo99
9223         rm -fr $DIR/$tdir.cvsroot
9224 }
9225 run_test 99 "cvs strange file/directory operations"
9226
9227 test_100() {
9228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9229         [[ "$NETTYPE" =~ tcp ]] ||
9230                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9231         remote_ost_nodsh && skip "remote OST with nodsh"
9232         remote_mds_nodsh && skip "remote MDS with nodsh"
9233         remote_servers ||
9234                 skip "useless for local single node setup"
9235
9236         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9237                 [ "$PROT" != "tcp" ] && continue
9238                 RPORT=$(echo $REMOTE | cut -d: -f2)
9239                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9240
9241                 rc=0
9242                 LPORT=`echo $LOCAL | cut -d: -f2`
9243                 if [ $LPORT -ge 1024 ]; then
9244                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9245                         netstat -tna
9246                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9247                 fi
9248         done
9249         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9250 }
9251 run_test 100 "check local port using privileged port ==========="
9252
9253 function get_named_value()
9254 {
9255     local tag
9256
9257     tag=$1
9258     while read ;do
9259         line=$REPLY
9260         case $line in
9261         $tag*)
9262             echo $line | sed "s/^$tag[ ]*//"
9263             break
9264             ;;
9265         esac
9266     done
9267 }
9268
9269 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9270                    awk '/^max_cached_mb/ { print $2 }')
9271
9272 cleanup_101a() {
9273         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9274         trap 0
9275 }
9276
9277 test_101a() {
9278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9279
9280         local s
9281         local discard
9282         local nreads=10000
9283         local cache_limit=32
9284
9285         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9286         trap cleanup_101a EXIT
9287         $LCTL set_param -n llite.*.read_ahead_stats 0
9288         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9289
9290         #
9291         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9292         #
9293         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9294         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9295
9296         discard=0
9297         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9298                 get_named_value 'read but discarded' | cut -d" " -f1); do
9299                         discard=$(($discard + $s))
9300         done
9301         cleanup_101a
9302
9303         $LCTL get_param osc.*-osc*.rpc_stats
9304         $LCTL get_param llite.*.read_ahead_stats
9305
9306         # Discard is generally zero, but sometimes a few random reads line up
9307         # and trigger larger readahead, which is wasted & leads to discards.
9308         if [[ $(($discard)) -gt $nreads ]]; then
9309                 error "too many ($discard) discarded pages"
9310         fi
9311         rm -f $DIR/$tfile || true
9312 }
9313 run_test 101a "check read-ahead for random reads"
9314
9315 setup_test101bc() {
9316         test_mkdir $DIR/$tdir
9317         local ssize=$1
9318         local FILE_LENGTH=$2
9319         STRIPE_OFFSET=0
9320
9321         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9322
9323         local list=$(comma_list $(osts_nodes))
9324         set_osd_param $list '' read_cache_enable 0
9325         set_osd_param $list '' writethrough_cache_enable 0
9326
9327         trap cleanup_test101bc EXIT
9328         # prepare the read-ahead file
9329         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9330
9331         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9332                                 count=$FILE_SIZE_MB 2> /dev/null
9333
9334 }
9335
9336 cleanup_test101bc() {
9337         trap 0
9338         rm -rf $DIR/$tdir
9339         rm -f $DIR/$tfile
9340
9341         local list=$(comma_list $(osts_nodes))
9342         set_osd_param $list '' read_cache_enable 1
9343         set_osd_param $list '' writethrough_cache_enable 1
9344 }
9345
9346 calc_total() {
9347         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9348 }
9349
9350 ra_check_101() {
9351         local READ_SIZE=$1
9352         local STRIPE_SIZE=$2
9353         local FILE_LENGTH=$3
9354         local RA_INC=1048576
9355         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9356         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9357                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9358         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9359                         get_named_value 'read but discarded' |
9360                         cut -d" " -f1 | calc_total)
9361         if [[ $DISCARD -gt $discard_limit ]]; then
9362                 $LCTL get_param llite.*.read_ahead_stats
9363                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9364         else
9365                 echo "Read-ahead success for size ${READ_SIZE}"
9366         fi
9367 }
9368
9369 test_101b() {
9370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9371         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9372
9373         local STRIPE_SIZE=1048576
9374         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9375
9376         if [ $SLOW == "yes" ]; then
9377                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9378         else
9379                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9380         fi
9381
9382         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9383
9384         # prepare the read-ahead file
9385         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9386         cancel_lru_locks osc
9387         for BIDX in 2 4 8 16 32 64 128 256
9388         do
9389                 local BSIZE=$((BIDX*4096))
9390                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9391                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9392                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9393                 $LCTL set_param -n llite.*.read_ahead_stats 0
9394                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9395                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9396                 cancel_lru_locks osc
9397                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9398         done
9399         cleanup_test101bc
9400         true
9401 }
9402 run_test 101b "check stride-io mode read-ahead ================="
9403
9404 test_101c() {
9405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9406
9407         local STRIPE_SIZE=1048576
9408         local FILE_LENGTH=$((STRIPE_SIZE*100))
9409         local nreads=10000
9410         local rsize=65536
9411         local osc_rpc_stats
9412
9413         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9414
9415         cancel_lru_locks osc
9416         $LCTL set_param osc.*.rpc_stats 0
9417         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9418         $LCTL get_param osc.*.rpc_stats
9419         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9420                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9421                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9422                 local size
9423
9424                 if [ $lines -le 20 ]; then
9425                         echo "continue debug"
9426                         continue
9427                 fi
9428                 for size in 1 2 4 8; do
9429                         local rpc=$(echo "$stats" |
9430                                     awk '($1 == "'$size':") {print $2; exit; }')
9431                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9432                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9433                 done
9434                 echo "$osc_rpc_stats check passed!"
9435         done
9436         cleanup_test101bc
9437         true
9438 }
9439 run_test 101c "check stripe_size aligned read-ahead ================="
9440
9441 test_101d() {
9442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9443
9444         local file=$DIR/$tfile
9445         local sz_MB=${FILESIZE_101d:-80}
9446         local ra_MB=${READAHEAD_MB:-40}
9447
9448         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9449         [ $free_MB -lt $sz_MB ] &&
9450                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9451
9452         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9453         $LFS setstripe -c -1 $file || error "setstripe failed"
9454
9455         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9456         echo Cancel LRU locks on lustre client to flush the client cache
9457         cancel_lru_locks osc
9458
9459         echo Disable read-ahead
9460         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9461         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9462         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9463         $LCTL get_param -n llite.*.max_read_ahead_mb
9464
9465         echo "Reading the test file $file with read-ahead disabled"
9466         local sz_KB=$((sz_MB * 1024 / 4))
9467         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9468         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9469         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9470                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9471
9472         echo "Cancel LRU locks on lustre client to flush the client cache"
9473         cancel_lru_locks osc
9474         echo Enable read-ahead with ${ra_MB}MB
9475         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9476
9477         echo "Reading the test file $file with read-ahead enabled"
9478         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9479                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9480
9481         echo "read-ahead disabled time read $raOFF"
9482         echo "read-ahead enabled time read $raON"
9483
9484         rm -f $file
9485         wait_delete_completed
9486
9487         # use awk for this check instead of bash because it handles decimals
9488         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9489                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9490 }
9491 run_test 101d "file read with and without read-ahead enabled"
9492
9493 test_101e() {
9494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9495
9496         local file=$DIR/$tfile
9497         local size_KB=500  #KB
9498         local count=100
9499         local bsize=1024
9500
9501         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9502         local need_KB=$((count * size_KB))
9503         [[ $free_KB -le $need_KB ]] &&
9504                 skip_env "Need free space $need_KB, have $free_KB"
9505
9506         echo "Creating $count ${size_KB}K test files"
9507         for ((i = 0; i < $count; i++)); do
9508                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9509         done
9510
9511         echo "Cancel LRU locks on lustre client to flush the client cache"
9512         cancel_lru_locks $OSC
9513
9514         echo "Reset readahead stats"
9515         $LCTL set_param -n llite.*.read_ahead_stats 0
9516
9517         for ((i = 0; i < $count; i++)); do
9518                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9519         done
9520
9521         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9522                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9523
9524         for ((i = 0; i < $count; i++)); do
9525                 rm -rf $file.$i 2>/dev/null
9526         done
9527
9528         #10000 means 20% reads are missing in readahead
9529         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9530 }
9531 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9532
9533 test_101f() {
9534         which iozone || skip_env "no iozone installed"
9535
9536         local old_debug=$($LCTL get_param debug)
9537         old_debug=${old_debug#*=}
9538         $LCTL set_param debug="reada mmap"
9539
9540         # create a test file
9541         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9542
9543         echo Cancel LRU locks on lustre client to flush the client cache
9544         cancel_lru_locks osc
9545
9546         echo Reset readahead stats
9547         $LCTL set_param -n llite.*.read_ahead_stats 0
9548
9549         echo mmap read the file with small block size
9550         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9551                 > /dev/null 2>&1
9552
9553         echo checking missing pages
9554         $LCTL get_param llite.*.read_ahead_stats
9555         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9556                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9557
9558         $LCTL set_param debug="$old_debug"
9559         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9560         rm -f $DIR/$tfile
9561 }
9562 run_test 101f "check mmap read performance"
9563
9564 test_101g_brw_size_test() {
9565         local mb=$1
9566         local pages=$((mb * 1048576 / PAGE_SIZE))
9567         local file=$DIR/$tfile
9568
9569         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9570                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9571         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9572                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9573                         return 2
9574         done
9575
9576         stack_trap "rm -f $file" EXIT
9577         $LCTL set_param -n osc.*.rpc_stats=0
9578
9579         # 10 RPCs should be enough for the test
9580         local count=10
9581         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9582                 { error "dd write ${mb} MB blocks failed"; return 3; }
9583         cancel_lru_locks osc
9584         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9585                 { error "dd write ${mb} MB blocks failed"; return 4; }
9586
9587         # calculate number of full-sized read and write RPCs
9588         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9589                 sed -n '/pages per rpc/,/^$/p' |
9590                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9591                 END { print reads,writes }'))
9592         # allow one extra full-sized read RPC for async readahead
9593         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9594                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9595         [[ ${rpcs[1]} == $count ]] ||
9596                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9597 }
9598
9599 test_101g() {
9600         remote_ost_nodsh && skip "remote OST with nodsh"
9601
9602         local rpcs
9603         local osts=$(get_facets OST)
9604         local list=$(comma_list $(osts_nodes))
9605         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9606         local brw_size="obdfilter.*.brw_size"
9607
9608         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9609
9610         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9611
9612         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9613                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9614                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9615            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9616                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9617                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9618
9619                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9620                         suffix="M"
9621
9622                 if [[ $orig_mb -lt 16 ]]; then
9623                         save_lustre_params $osts "$brw_size" > $p
9624                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9625                                 error "set 16MB RPC size failed"
9626
9627                         echo "remount client to enable new RPC size"
9628                         remount_client $MOUNT || error "remount_client failed"
9629                 fi
9630
9631                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9632                 # should be able to set brw_size=12, but no rpc_stats for that
9633                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9634         fi
9635
9636         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9637
9638         if [[ $orig_mb -lt 16 ]]; then
9639                 restore_lustre_params < $p
9640                 remount_client $MOUNT || error "remount_client restore failed"
9641         fi
9642
9643         rm -f $p $DIR/$tfile
9644 }
9645 run_test 101g "Big bulk(4/16 MiB) readahead"
9646
9647 test_101h() {
9648         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9649
9650         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9651                 error "dd 70M file failed"
9652         echo Cancel LRU locks on lustre client to flush the client cache
9653         cancel_lru_locks osc
9654
9655         echo "Reset readahead stats"
9656         $LCTL set_param -n llite.*.read_ahead_stats 0
9657
9658         echo "Read 10M of data but cross 64M bundary"
9659         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9660         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9661                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9662         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9663         rm -f $p $DIR/$tfile
9664 }
9665 run_test 101h "Readahead should cover current read window"
9666
9667 test_101i() {
9668         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9669                 error "dd 10M file failed"
9670
9671         local max_per_file_mb=$($LCTL get_param -n \
9672                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9673         cancel_lru_locks osc
9674         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9675         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9676                 error "set max_read_ahead_per_file_mb to 1 failed"
9677
9678         echo "Reset readahead stats"
9679         $LCTL set_param llite.*.read_ahead_stats=0
9680
9681         dd if=$DIR/$tfile of=/dev/null bs=2M
9682
9683         $LCTL get_param llite.*.read_ahead_stats
9684         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9685                      awk '/misses/ { print $2 }')
9686         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9687         rm -f $DIR/$tfile
9688 }
9689 run_test 101i "allow current readahead to exceed reservation"
9690
9691 test_101j() {
9692         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9693                 error "setstripe $DIR/$tfile failed"
9694         local file_size=$((1048576 * 16))
9695         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9696         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9697
9698         echo Disable read-ahead
9699         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9700
9701         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9702         for blk in $PAGE_SIZE 1048576 $file_size; do
9703                 cancel_lru_locks osc
9704                 echo "Reset readahead stats"
9705                 $LCTL set_param -n llite.*.read_ahead_stats=0
9706                 local count=$(($file_size / $blk))
9707                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9708                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9709                              get_named_value 'failed to fast read' |
9710                              cut -d" " -f1 | calc_total)
9711                 $LCTL get_param -n llite.*.read_ahead_stats
9712                 [ $miss -eq $count ] || error "expected $count got $miss"
9713         done
9714
9715         rm -f $p $DIR/$tfile
9716 }
9717 run_test 101j "A complete read block should be submitted when no RA"
9718
9719 setup_test102() {
9720         test_mkdir $DIR/$tdir
9721         chown $RUNAS_ID $DIR/$tdir
9722         STRIPE_SIZE=65536
9723         STRIPE_OFFSET=1
9724         STRIPE_COUNT=$OSTCOUNT
9725         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9726
9727         trap cleanup_test102 EXIT
9728         cd $DIR
9729         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9730         cd $DIR/$tdir
9731         for num in 1 2 3 4; do
9732                 for count in $(seq 1 $STRIPE_COUNT); do
9733                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9734                                 local size=`expr $STRIPE_SIZE \* $num`
9735                                 local file=file"$num-$idx-$count"
9736                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9737                         done
9738                 done
9739         done
9740
9741         cd $DIR
9742         $1 tar cf $TMP/f102.tar $tdir --xattrs
9743 }
9744
9745 cleanup_test102() {
9746         trap 0
9747         rm -f $TMP/f102.tar
9748         rm -rf $DIR/d0.sanity/d102
9749 }
9750
9751 test_102a() {
9752         [ "$UID" != 0 ] && skip "must run as root"
9753         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9754                 skip_env "must have user_xattr"
9755
9756         [ -z "$(which setfattr 2>/dev/null)" ] &&
9757                 skip_env "could not find setfattr"
9758
9759         local testfile=$DIR/$tfile
9760
9761         touch $testfile
9762         echo "set/get xattr..."
9763         setfattr -n trusted.name1 -v value1 $testfile ||
9764                 error "setfattr -n trusted.name1=value1 $testfile failed"
9765         getfattr -n trusted.name1 $testfile 2> /dev/null |
9766           grep "trusted.name1=.value1" ||
9767                 error "$testfile missing trusted.name1=value1"
9768
9769         setfattr -n user.author1 -v author1 $testfile ||
9770                 error "setfattr -n user.author1=author1 $testfile failed"
9771         getfattr -n user.author1 $testfile 2> /dev/null |
9772           grep "user.author1=.author1" ||
9773                 error "$testfile missing trusted.author1=author1"
9774
9775         echo "listxattr..."
9776         setfattr -n trusted.name2 -v value2 $testfile ||
9777                 error "$testfile unable to set trusted.name2"
9778         setfattr -n trusted.name3 -v value3 $testfile ||
9779                 error "$testfile unable to set trusted.name3"
9780         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9781             grep "trusted.name" | wc -l) -eq 3 ] ||
9782                 error "$testfile missing 3 trusted.name xattrs"
9783
9784         setfattr -n user.author2 -v author2 $testfile ||
9785                 error "$testfile unable to set user.author2"
9786         setfattr -n user.author3 -v author3 $testfile ||
9787                 error "$testfile unable to set user.author3"
9788         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9789             grep "user.author" | wc -l) -eq 3 ] ||
9790                 error "$testfile missing 3 user.author xattrs"
9791
9792         echo "remove xattr..."
9793         setfattr -x trusted.name1 $testfile ||
9794                 error "$testfile error deleting trusted.name1"
9795         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9796                 error "$testfile did not delete trusted.name1 xattr"
9797
9798         setfattr -x user.author1 $testfile ||
9799                 error "$testfile error deleting user.author1"
9800         echo "set lustre special xattr ..."
9801         $LFS setstripe -c1 $testfile
9802         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9803                 awk -F "=" '/trusted.lov/ { print $2 }' )
9804         setfattr -n "trusted.lov" -v $lovea $testfile ||
9805                 error "$testfile doesn't ignore setting trusted.lov again"
9806         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9807                 error "$testfile allow setting invalid trusted.lov"
9808         rm -f $testfile
9809 }
9810 run_test 102a "user xattr test =================================="
9811
9812 check_102b_layout() {
9813         local layout="$*"
9814         local testfile=$DIR/$tfile
9815
9816         echo "test layout '$layout'"
9817         $LFS setstripe $layout $testfile || error "setstripe failed"
9818         $LFS getstripe -y $testfile
9819
9820         echo "get/set/list trusted.lov xattr ..." # b=10930
9821         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9822         [[ "$value" =~ "trusted.lov" ]] ||
9823                 error "can't get trusted.lov from $testfile"
9824         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9825                 error "getstripe failed"
9826
9827         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9828
9829         value=$(cut -d= -f2 <<<$value)
9830         # LU-13168: truncated xattr should fail if short lov_user_md header
9831         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9832                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9833         for len in $lens; do
9834                 echo "setfattr $len $testfile.2"
9835                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9836                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9837         done
9838         local stripe_size=$($LFS getstripe -S $testfile.2)
9839         local stripe_count=$($LFS getstripe -c $testfile.2)
9840         [[ $stripe_size -eq 65536 ]] ||
9841                 error "stripe size $stripe_size != 65536"
9842         [[ $stripe_count -eq $stripe_count_orig ]] ||
9843                 error "stripe count $stripe_count != $stripe_count_orig"
9844         rm $testfile $testfile.2
9845 }
9846
9847 test_102b() {
9848         [ -z "$(which setfattr 2>/dev/null)" ] &&
9849                 skip_env "could not find setfattr"
9850         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9851
9852         # check plain layout
9853         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9854
9855         # and also check composite layout
9856         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9857
9858 }
9859 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9860
9861 test_102c() {
9862         [ -z "$(which setfattr 2>/dev/null)" ] &&
9863                 skip_env "could not find setfattr"
9864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9865
9866         # b10930: get/set/list lustre.lov xattr
9867         echo "get/set/list lustre.lov xattr ..."
9868         test_mkdir $DIR/$tdir
9869         chown $RUNAS_ID $DIR/$tdir
9870         local testfile=$DIR/$tdir/$tfile
9871         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9872                 error "setstripe failed"
9873         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9874                 error "getstripe failed"
9875         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9876         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9877
9878         local testfile2=${testfile}2
9879         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9880                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9881
9882         $RUNAS $MCREATE $testfile2
9883         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9884         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9885         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9886         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9887         [ $stripe_count -eq $STRIPECOUNT ] ||
9888                 error "stripe count $stripe_count != $STRIPECOUNT"
9889 }
9890 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9891
9892 compare_stripe_info1() {
9893         local stripe_index_all_zero=true
9894
9895         for num in 1 2 3 4; do
9896                 for count in $(seq 1 $STRIPE_COUNT); do
9897                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9898                                 local size=$((STRIPE_SIZE * num))
9899                                 local file=file"$num-$offset-$count"
9900                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9901                                 [[ $stripe_size -ne $size ]] &&
9902                                     error "$file: size $stripe_size != $size"
9903                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9904                                 # allow fewer stripes to be created, ORI-601
9905                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9906                                     error "$file: count $stripe_count != $count"
9907                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9908                                 [[ $stripe_index -ne 0 ]] &&
9909                                         stripe_index_all_zero=false
9910                         done
9911                 done
9912         done
9913         $stripe_index_all_zero &&
9914                 error "all files are being extracted starting from OST index 0"
9915         return 0
9916 }
9917
9918 have_xattrs_include() {
9919         tar --help | grep -q xattrs-include &&
9920                 echo --xattrs-include="lustre.*"
9921 }
9922
9923 test_102d() {
9924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9926
9927         XINC=$(have_xattrs_include)
9928         setup_test102
9929         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9930         cd $DIR/$tdir/$tdir
9931         compare_stripe_info1
9932 }
9933 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9934
9935 test_102f() {
9936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9938
9939         XINC=$(have_xattrs_include)
9940         setup_test102
9941         test_mkdir $DIR/$tdir.restore
9942         cd $DIR
9943         tar cf - --xattrs $tdir | tar xf - \
9944                 -C $DIR/$tdir.restore --xattrs $XINC
9945         cd $DIR/$tdir.restore/$tdir
9946         compare_stripe_info1
9947 }
9948 run_test 102f "tar copy files, not keep osts"
9949
9950 grow_xattr() {
9951         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9952                 skip "must have user_xattr"
9953         [ -z "$(which setfattr 2>/dev/null)" ] &&
9954                 skip_env "could not find setfattr"
9955         [ -z "$(which getfattr 2>/dev/null)" ] &&
9956                 skip_env "could not find getfattr"
9957
9958         local xsize=${1:-1024}  # in bytes
9959         local file=$DIR/$tfile
9960         local value="$(generate_string $xsize)"
9961         local xbig=trusted.big
9962         local toobig=$2
9963
9964         touch $file
9965         log "save $xbig on $file"
9966         if [ -z "$toobig" ]
9967         then
9968                 setfattr -n $xbig -v $value $file ||
9969                         error "saving $xbig on $file failed"
9970         else
9971                 setfattr -n $xbig -v $value $file &&
9972                         error "saving $xbig on $file succeeded"
9973                 return 0
9974         fi
9975
9976         local orig=$(get_xattr_value $xbig $file)
9977         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9978
9979         local xsml=trusted.sml
9980         log "save $xsml on $file"
9981         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9982
9983         local new=$(get_xattr_value $xbig $file)
9984         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9985
9986         log "grow $xsml on $file"
9987         setfattr -n $xsml -v "$value" $file ||
9988                 error "growing $xsml on $file failed"
9989
9990         new=$(get_xattr_value $xbig $file)
9991         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9992         log "$xbig still valid after growing $xsml"
9993
9994         rm -f $file
9995 }
9996
9997 test_102h() { # bug 15777
9998         grow_xattr 1024
9999 }
10000 run_test 102h "grow xattr from inside inode to external block"
10001
10002 test_102ha() {
10003         large_xattr_enabled || skip_env "ea_inode feature disabled"
10004
10005         echo "setting xattr of max xattr size: $(max_xattr_size)"
10006         grow_xattr $(max_xattr_size)
10007
10008         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10009         echo "This should fail:"
10010         grow_xattr $(($(max_xattr_size) + 10)) 1
10011 }
10012 run_test 102ha "grow xattr from inside inode to external inode"
10013
10014 test_102i() { # bug 17038
10015         [ -z "$(which getfattr 2>/dev/null)" ] &&
10016                 skip "could not find getfattr"
10017
10018         touch $DIR/$tfile
10019         ln -s $DIR/$tfile $DIR/${tfile}link
10020         getfattr -n trusted.lov $DIR/$tfile ||
10021                 error "lgetxattr on $DIR/$tfile failed"
10022         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10023                 grep -i "no such attr" ||
10024                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10025         rm -f $DIR/$tfile $DIR/${tfile}link
10026 }
10027 run_test 102i "lgetxattr test on symbolic link ============"
10028
10029 test_102j() {
10030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10031         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10032
10033         XINC=$(have_xattrs_include)
10034         setup_test102 "$RUNAS"
10035         chown $RUNAS_ID $DIR/$tdir
10036         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10037         cd $DIR/$tdir/$tdir
10038         compare_stripe_info1 "$RUNAS"
10039 }
10040 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10041
10042 test_102k() {
10043         [ -z "$(which setfattr 2>/dev/null)" ] &&
10044                 skip "could not find setfattr"
10045
10046         touch $DIR/$tfile
10047         # b22187 just check that does not crash for regular file.
10048         setfattr -n trusted.lov $DIR/$tfile
10049         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10050         local test_kdir=$DIR/$tdir
10051         test_mkdir $test_kdir
10052         local default_size=$($LFS getstripe -S $test_kdir)
10053         local default_count=$($LFS getstripe -c $test_kdir)
10054         local default_offset=$($LFS getstripe -i $test_kdir)
10055         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10056                 error 'dir setstripe failed'
10057         setfattr -n trusted.lov $test_kdir
10058         local stripe_size=$($LFS getstripe -S $test_kdir)
10059         local stripe_count=$($LFS getstripe -c $test_kdir)
10060         local stripe_offset=$($LFS getstripe -i $test_kdir)
10061         [ $stripe_size -eq $default_size ] ||
10062                 error "stripe size $stripe_size != $default_size"
10063         [ $stripe_count -eq $default_count ] ||
10064                 error "stripe count $stripe_count != $default_count"
10065         [ $stripe_offset -eq $default_offset ] ||
10066                 error "stripe offset $stripe_offset != $default_offset"
10067         rm -rf $DIR/$tfile $test_kdir
10068 }
10069 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10070
10071 test_102l() {
10072         [ -z "$(which getfattr 2>/dev/null)" ] &&
10073                 skip "could not find getfattr"
10074
10075         # LU-532 trusted. xattr is invisible to non-root
10076         local testfile=$DIR/$tfile
10077
10078         touch $testfile
10079
10080         echo "listxattr as user..."
10081         chown $RUNAS_ID $testfile
10082         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10083             grep -q "trusted" &&
10084                 error "$testfile trusted xattrs are user visible"
10085
10086         return 0;
10087 }
10088 run_test 102l "listxattr size test =================================="
10089
10090 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10091         local path=$DIR/$tfile
10092         touch $path
10093
10094         listxattr_size_check $path || error "listattr_size_check $path failed"
10095 }
10096 run_test 102m "Ensure listxattr fails on small bufffer ========"
10097
10098 cleanup_test102
10099
10100 getxattr() { # getxattr path name
10101         # Return the base64 encoding of the value of xattr name on path.
10102         local path=$1
10103         local name=$2
10104
10105         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10106         # file: $path
10107         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10108         #
10109         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10110
10111         getfattr --absolute-names --encoding=base64 --name=$name $path |
10112                 awk -F= -v name=$name '$1 == name {
10113                         print substr($0, index($0, "=") + 1);
10114         }'
10115 }
10116
10117 test_102n() { # LU-4101 mdt: protect internal xattrs
10118         [ -z "$(which setfattr 2>/dev/null)" ] &&
10119                 skip "could not find setfattr"
10120         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10121         then
10122                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10123         fi
10124
10125         local file0=$DIR/$tfile.0
10126         local file1=$DIR/$tfile.1
10127         local xattr0=$TMP/$tfile.0
10128         local xattr1=$TMP/$tfile.1
10129         local namelist="lov lma lmv link fid version som hsm"
10130         local name
10131         local value
10132
10133         rm -rf $file0 $file1 $xattr0 $xattr1
10134         touch $file0 $file1
10135
10136         # Get 'before' xattrs of $file1.
10137         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10138
10139         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10140                 namelist+=" lfsck_namespace"
10141         for name in $namelist; do
10142                 # Try to copy xattr from $file0 to $file1.
10143                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10144
10145                 setfattr --name=trusted.$name --value="$value" $file1 ||
10146                         error "setxattr 'trusted.$name' failed"
10147
10148                 # Try to set a garbage xattr.
10149                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10150
10151                 if [[ x$name == "xlov" ]]; then
10152                         setfattr --name=trusted.lov --value="$value" $file1 &&
10153                         error "setxattr invalid 'trusted.lov' success"
10154                 else
10155                         setfattr --name=trusted.$name --value="$value" $file1 ||
10156                                 error "setxattr invalid 'trusted.$name' failed"
10157                 fi
10158
10159                 # Try to remove the xattr from $file1. We don't care if this
10160                 # appears to succeed or fail, we just don't want there to be
10161                 # any changes or crashes.
10162                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10163         done
10164
10165         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10166         then
10167                 name="lfsck_ns"
10168                 # Try to copy xattr from $file0 to $file1.
10169                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10170
10171                 setfattr --name=trusted.$name --value="$value" $file1 ||
10172                         error "setxattr 'trusted.$name' failed"
10173
10174                 # Try to set a garbage xattr.
10175                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10176
10177                 setfattr --name=trusted.$name --value="$value" $file1 ||
10178                         error "setxattr 'trusted.$name' failed"
10179
10180                 # Try to remove the xattr from $file1. We don't care if this
10181                 # appears to succeed or fail, we just don't want there to be
10182                 # any changes or crashes.
10183                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10184         fi
10185
10186         # Get 'after' xattrs of file1.
10187         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10188
10189         if ! diff $xattr0 $xattr1; then
10190                 error "before and after xattrs of '$file1' differ"
10191         fi
10192
10193         rm -rf $file0 $file1 $xattr0 $xattr1
10194
10195         return 0
10196 }
10197 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10198
10199 test_102p() { # LU-4703 setxattr did not check ownership
10200         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10201                 skip "MDS needs to be at least 2.5.56"
10202
10203         local testfile=$DIR/$tfile
10204
10205         touch $testfile
10206
10207         echo "setfacl as user..."
10208         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10209         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10210
10211         echo "setfattr as user..."
10212         setfacl -m "u:$RUNAS_ID:---" $testfile
10213         $RUNAS setfattr -x system.posix_acl_access $testfile
10214         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10215 }
10216 run_test 102p "check setxattr(2) correctly fails without permission"
10217
10218 test_102q() {
10219         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10220                 skip "MDS needs to be at least 2.6.92"
10221
10222         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10223 }
10224 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10225
10226 test_102r() {
10227         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10228                 skip "MDS needs to be at least 2.6.93"
10229
10230         touch $DIR/$tfile || error "touch"
10231         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10232         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10233         rm $DIR/$tfile || error "rm"
10234
10235         #normal directory
10236         mkdir -p $DIR/$tdir || error "mkdir"
10237         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10238         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10239         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10240                 error "$testfile error deleting user.author1"
10241         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10242                 grep "user.$(basename $tdir)" &&
10243                 error "$tdir did not delete user.$(basename $tdir)"
10244         rmdir $DIR/$tdir || error "rmdir"
10245
10246         #striped directory
10247         test_mkdir $DIR/$tdir
10248         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10249         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10250         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10251                 error "$testfile error deleting user.author1"
10252         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10253                 grep "user.$(basename $tdir)" &&
10254                 error "$tdir did not delete user.$(basename $tdir)"
10255         rmdir $DIR/$tdir || error "rm striped dir"
10256 }
10257 run_test 102r "set EAs with empty values"
10258
10259 test_102s() {
10260         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10261                 skip "MDS needs to be at least 2.11.52"
10262
10263         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10264
10265         save_lustre_params client "llite.*.xattr_cache" > $save
10266
10267         for cache in 0 1; do
10268                 lctl set_param llite.*.xattr_cache=$cache
10269
10270                 rm -f $DIR/$tfile
10271                 touch $DIR/$tfile || error "touch"
10272                 for prefix in lustre security system trusted user; do
10273                         # Note getxattr() may fail with 'Operation not
10274                         # supported' or 'No such attribute' depending
10275                         # on prefix and cache.
10276                         getfattr -n $prefix.n102s $DIR/$tfile &&
10277                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10278                 done
10279         done
10280
10281         restore_lustre_params < $save
10282 }
10283 run_test 102s "getting nonexistent xattrs should fail"
10284
10285 test_102t() {
10286         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10287                 skip "MDS needs to be at least 2.11.52"
10288
10289         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10290
10291         save_lustre_params client "llite.*.xattr_cache" > $save
10292
10293         for cache in 0 1; do
10294                 lctl set_param llite.*.xattr_cache=$cache
10295
10296                 for buf_size in 0 256; do
10297                         rm -f $DIR/$tfile
10298                         touch $DIR/$tfile || error "touch"
10299                         setfattr -n user.multiop $DIR/$tfile
10300                         $MULTIOP $DIR/$tfile oa$buf_size ||
10301                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10302                 done
10303         done
10304
10305         restore_lustre_params < $save
10306 }
10307 run_test 102t "zero length xattr values handled correctly"
10308
10309 run_acl_subtest()
10310 {
10311     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10312     return $?
10313 }
10314
10315 test_103a() {
10316         [ "$UID" != 0 ] && skip "must run as root"
10317         $GSS && skip_env "could not run under gss"
10318         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10319                 skip_env "must have acl enabled"
10320         [ -z "$(which setfacl 2>/dev/null)" ] &&
10321                 skip_env "could not find setfacl"
10322         remote_mds_nodsh && skip "remote MDS with nodsh"
10323
10324         gpasswd -a daemon bin                           # LU-5641
10325         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10326
10327         declare -a identity_old
10328
10329         for num in $(seq $MDSCOUNT); do
10330                 switch_identity $num true || identity_old[$num]=$?
10331         done
10332
10333         SAVE_UMASK=$(umask)
10334         umask 0022
10335         mkdir -p $DIR/$tdir
10336         cd $DIR/$tdir
10337
10338         echo "performing cp ..."
10339         run_acl_subtest cp || error "run_acl_subtest cp failed"
10340         echo "performing getfacl-noacl..."
10341         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10342         echo "performing misc..."
10343         run_acl_subtest misc || error  "misc test failed"
10344         echo "performing permissions..."
10345         run_acl_subtest permissions || error "permissions failed"
10346         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10347         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10348                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10349                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10350         then
10351                 echo "performing permissions xattr..."
10352                 run_acl_subtest permissions_xattr ||
10353                         error "permissions_xattr failed"
10354         fi
10355         echo "performing setfacl..."
10356         run_acl_subtest setfacl || error  "setfacl test failed"
10357
10358         # inheritance test got from HP
10359         echo "performing inheritance..."
10360         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10361         chmod +x make-tree || error "chmod +x failed"
10362         run_acl_subtest inheritance || error "inheritance test failed"
10363         rm -f make-tree
10364
10365         echo "LU-974 ignore umask when acl is enabled..."
10366         run_acl_subtest 974 || error "LU-974 umask test failed"
10367         if [ $MDSCOUNT -ge 2 ]; then
10368                 run_acl_subtest 974_remote ||
10369                         error "LU-974 umask test failed under remote dir"
10370         fi
10371
10372         echo "LU-2561 newly created file is same size as directory..."
10373         if [ "$mds1_FSTYPE" != "zfs" ]; then
10374                 run_acl_subtest 2561 || error "LU-2561 test failed"
10375         else
10376                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10377         fi
10378
10379         run_acl_subtest 4924 || error "LU-4924 test failed"
10380
10381         cd $SAVE_PWD
10382         umask $SAVE_UMASK
10383
10384         for num in $(seq $MDSCOUNT); do
10385                 if [ "${identity_old[$num]}" = 1 ]; then
10386                         switch_identity $num false || identity_old[$num]=$?
10387                 fi
10388         done
10389 }
10390 run_test 103a "acl test"
10391
10392 test_103b() {
10393         declare -a pids
10394         local U
10395
10396         for U in {0..511}; do
10397                 {
10398                 local O=$(printf "%04o" $U)
10399
10400                 umask $(printf "%04o" $((511 ^ $O)))
10401                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10402                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10403
10404                 (( $S == ($O & 0666) )) ||
10405                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10406
10407                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10408                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10409                 (( $S == ($O & 0666) )) ||
10410                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10411
10412                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10413                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10414                 (( $S == ($O & 0666) )) ||
10415                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10416                 rm -f $DIR/$tfile.[smp]$0
10417                 } &
10418                 local pid=$!
10419
10420                 # limit the concurrently running threads to 64. LU-11878
10421                 local idx=$((U % 64))
10422                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10423                 pids[idx]=$pid
10424         done
10425         wait
10426 }
10427 run_test 103b "umask lfs setstripe"
10428
10429 test_103c() {
10430         mkdir -p $DIR/$tdir
10431         cp -rp $DIR/$tdir $DIR/$tdir.bak
10432
10433         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10434                 error "$DIR/$tdir shouldn't contain default ACL"
10435         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10436                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10437         true
10438 }
10439 run_test 103c "'cp -rp' won't set empty acl"
10440
10441 test_104a() {
10442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10443
10444         touch $DIR/$tfile
10445         lfs df || error "lfs df failed"
10446         lfs df -ih || error "lfs df -ih failed"
10447         lfs df -h $DIR || error "lfs df -h $DIR failed"
10448         lfs df -i $DIR || error "lfs df -i $DIR failed"
10449         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10450         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10451
10452         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10453         lctl --device %$OSC deactivate
10454         lfs df || error "lfs df with deactivated OSC failed"
10455         lctl --device %$OSC activate
10456         # wait the osc back to normal
10457         wait_osc_import_ready client ost
10458
10459         lfs df || error "lfs df with reactivated OSC failed"
10460         rm -f $DIR/$tfile
10461 }
10462 run_test 104a "lfs df [-ih] [path] test ========================="
10463
10464 test_104b() {
10465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10466         [ $RUNAS_ID -eq $UID ] &&
10467                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10468
10469         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10470                         grep "Permission denied" | wc -l)))
10471         if [ $denied_cnt -ne 0 ]; then
10472                 error "lfs check servers test failed"
10473         fi
10474 }
10475 run_test 104b "$RUNAS lfs check servers test ===================="
10476
10477 test_105a() {
10478         # doesn't work on 2.4 kernels
10479         touch $DIR/$tfile
10480         if $(flock_is_enabled); then
10481                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10482         else
10483                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10484         fi
10485         rm -f $DIR/$tfile
10486 }
10487 run_test 105a "flock when mounted without -o flock test ========"
10488
10489 test_105b() {
10490         touch $DIR/$tfile
10491         if $(flock_is_enabled); then
10492                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10493         else
10494                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10495         fi
10496         rm -f $DIR/$tfile
10497 }
10498 run_test 105b "fcntl when mounted without -o flock test ========"
10499
10500 test_105c() {
10501         touch $DIR/$tfile
10502         if $(flock_is_enabled); then
10503                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10504         else
10505                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10506         fi
10507         rm -f $DIR/$tfile
10508 }
10509 run_test 105c "lockf when mounted without -o flock test"
10510
10511 test_105d() { # bug 15924
10512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10513
10514         test_mkdir $DIR/$tdir
10515         flock_is_enabled || skip_env "mount w/o flock enabled"
10516         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10517         $LCTL set_param fail_loc=0x80000315
10518         flocks_test 2 $DIR/$tdir
10519 }
10520 run_test 105d "flock race (should not freeze) ========"
10521
10522 test_105e() { # bug 22660 && 22040
10523         flock_is_enabled || skip_env "mount w/o flock enabled"
10524
10525         touch $DIR/$tfile
10526         flocks_test 3 $DIR/$tfile
10527 }
10528 run_test 105e "Two conflicting flocks from same process"
10529
10530 test_106() { #bug 10921
10531         test_mkdir $DIR/$tdir
10532         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10533         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10534 }
10535 run_test 106 "attempt exec of dir followed by chown of that dir"
10536
10537 test_107() {
10538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10539
10540         CDIR=`pwd`
10541         local file=core
10542
10543         cd $DIR
10544         rm -f $file
10545
10546         local save_pattern=$(sysctl -n kernel.core_pattern)
10547         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10548         sysctl -w kernel.core_pattern=$file
10549         sysctl -w kernel.core_uses_pid=0
10550
10551         ulimit -c unlimited
10552         sleep 60 &
10553         SLEEPPID=$!
10554
10555         sleep 1
10556
10557         kill -s 11 $SLEEPPID
10558         wait $SLEEPPID
10559         if [ -e $file ]; then
10560                 size=`stat -c%s $file`
10561                 [ $size -eq 0 ] && error "Fail to create core file $file"
10562         else
10563                 error "Fail to create core file $file"
10564         fi
10565         rm -f $file
10566         sysctl -w kernel.core_pattern=$save_pattern
10567         sysctl -w kernel.core_uses_pid=$save_uses_pid
10568         cd $CDIR
10569 }
10570 run_test 107 "Coredump on SIG"
10571
10572 test_110() {
10573         test_mkdir $DIR/$tdir
10574         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10575         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10576                 error "mkdir with 256 char should fail, but did not"
10577         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10578                 error "create with 255 char failed"
10579         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10580                 error "create with 256 char should fail, but did not"
10581
10582         ls -l $DIR/$tdir
10583         rm -rf $DIR/$tdir
10584 }
10585 run_test 110 "filename length checking"
10586
10587 #
10588 # Purpose: To verify dynamic thread (OSS) creation.
10589 #
10590 test_115() {
10591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10592         remote_ost_nodsh && skip "remote OST with nodsh"
10593
10594         # Lustre does not stop service threads once they are started.
10595         # Reset number of running threads to default.
10596         stopall
10597         setupall
10598
10599         local OSTIO_pre
10600         local save_params="$TMP/sanity-$TESTNAME.parameters"
10601
10602         # Get ll_ost_io count before I/O
10603         OSTIO_pre=$(do_facet ost1 \
10604                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10605         # Exit if lustre is not running (ll_ost_io not running).
10606         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10607
10608         echo "Starting with $OSTIO_pre threads"
10609         local thread_max=$((OSTIO_pre * 2))
10610         local rpc_in_flight=$((thread_max * 2))
10611         # Number of I/O Process proposed to be started.
10612         local nfiles
10613         local facets=$(get_facets OST)
10614
10615         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10616         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10617
10618         # Set in_flight to $rpc_in_flight
10619         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10620                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10621         nfiles=${rpc_in_flight}
10622         # Set ost thread_max to $thread_max
10623         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10624
10625         # 5 Minutes should be sufficient for max number of OSS
10626         # threads(thread_max) to be created.
10627         local timeout=300
10628
10629         # Start I/O.
10630         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10631         test_mkdir $DIR/$tdir
10632         for i in $(seq $nfiles); do
10633                 local file=$DIR/$tdir/${tfile}-$i
10634                 $LFS setstripe -c -1 -i 0 $file
10635                 ($WTL $file $timeout)&
10636         done
10637
10638         # I/O Started - Wait for thread_started to reach thread_max or report
10639         # error if thread_started is more than thread_max.
10640         echo "Waiting for thread_started to reach thread_max"
10641         local thread_started=0
10642         local end_time=$((SECONDS + timeout))
10643
10644         while [ $SECONDS -le $end_time ] ; do
10645                 echo -n "."
10646                 # Get ost i/o thread_started count.
10647                 thread_started=$(do_facet ost1 \
10648                         "$LCTL get_param \
10649                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10650                 # Break out if thread_started is equal/greater than thread_max
10651                 if [[ $thread_started -ge $thread_max ]]; then
10652                         echo ll_ost_io thread_started $thread_started, \
10653                                 equal/greater than thread_max $thread_max
10654                         break
10655                 fi
10656                 sleep 1
10657         done
10658
10659         # Cleanup - We have the numbers, Kill i/o jobs if running.
10660         jobcount=($(jobs -p))
10661         for i in $(seq 0 $((${#jobcount[@]}-1)))
10662         do
10663                 kill -9 ${jobcount[$i]}
10664                 if [ $? -ne 0 ] ; then
10665                         echo Warning: \
10666                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10667                 fi
10668         done
10669
10670         # Cleanup files left by WTL binary.
10671         for i in $(seq $nfiles); do
10672                 local file=$DIR/$tdir/${tfile}-$i
10673                 rm -rf $file
10674                 if [ $? -ne 0 ] ; then
10675                         echo "Warning: Failed to delete file $file"
10676                 fi
10677         done
10678
10679         restore_lustre_params <$save_params
10680         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10681
10682         # Error out if no new thread has started or Thread started is greater
10683         # than thread max.
10684         if [[ $thread_started -le $OSTIO_pre ||
10685                         $thread_started -gt $thread_max ]]; then
10686                 error "ll_ost_io: thread_started $thread_started" \
10687                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10688                       "No new thread started or thread started greater " \
10689                       "than thread_max."
10690         fi
10691 }
10692 run_test 115 "verify dynamic thread creation===================="
10693
10694 free_min_max () {
10695         wait_delete_completed
10696         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10697         echo "OST kbytes available: ${AVAIL[@]}"
10698         MAXV=${AVAIL[0]}
10699         MAXI=0
10700         MINV=${AVAIL[0]}
10701         MINI=0
10702         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10703                 #echo OST $i: ${AVAIL[i]}kb
10704                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10705                         MAXV=${AVAIL[i]}
10706                         MAXI=$i
10707                 fi
10708                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10709                         MINV=${AVAIL[i]}
10710                         MINI=$i
10711                 fi
10712         done
10713         echo "Min free space: OST $MINI: $MINV"
10714         echo "Max free space: OST $MAXI: $MAXV"
10715 }
10716
10717 test_116a() { # was previously test_116()
10718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10719         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10720         remote_mds_nodsh && skip "remote MDS with nodsh"
10721
10722         echo -n "Free space priority "
10723         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10724                 head -n1
10725         declare -a AVAIL
10726         free_min_max
10727
10728         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10729         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10730         trap simple_cleanup_common EXIT
10731
10732         # Check if we need to generate uneven OSTs
10733         test_mkdir -p $DIR/$tdir/OST${MINI}
10734         local FILL=$((MINV / 4))
10735         local DIFF=$((MAXV - MINV))
10736         local DIFF2=$((DIFF * 100 / MINV))
10737
10738         local threshold=$(do_facet $SINGLEMDS \
10739                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10740         threshold=${threshold%%%}
10741         echo -n "Check for uneven OSTs: "
10742         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10743
10744         if [[ $DIFF2 -gt $threshold ]]; then
10745                 echo "ok"
10746                 echo "Don't need to fill OST$MINI"
10747         else
10748                 # generate uneven OSTs. Write 2% over the QOS threshold value
10749                 echo "no"
10750                 DIFF=$((threshold - DIFF2 + 2))
10751                 DIFF2=$((MINV * DIFF / 100))
10752                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10753                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10754                         error "setstripe failed"
10755                 DIFF=$((DIFF2 / 2048))
10756                 i=0
10757                 while [ $i -lt $DIFF ]; do
10758                         i=$((i + 1))
10759                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10760                                 bs=2M count=1 2>/dev/null
10761                         echo -n .
10762                 done
10763                 echo .
10764                 sync
10765                 sleep_maxage
10766                 free_min_max
10767         fi
10768
10769         DIFF=$((MAXV - MINV))
10770         DIFF2=$((DIFF * 100 / MINV))
10771         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10772         if [ $DIFF2 -gt $threshold ]; then
10773                 echo "ok"
10774         else
10775                 echo "failed - QOS mode won't be used"
10776                 simple_cleanup_common
10777                 skip "QOS imbalance criteria not met"
10778         fi
10779
10780         MINI1=$MINI
10781         MINV1=$MINV
10782         MAXI1=$MAXI
10783         MAXV1=$MAXV
10784
10785         # now fill using QOS
10786         $LFS setstripe -c 1 $DIR/$tdir
10787         FILL=$((FILL / 200))
10788         if [ $FILL -gt 600 ]; then
10789                 FILL=600
10790         fi
10791         echo "writing $FILL files to QOS-assigned OSTs"
10792         i=0
10793         while [ $i -lt $FILL ]; do
10794                 i=$((i + 1))
10795                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10796                         count=1 2>/dev/null
10797                 echo -n .
10798         done
10799         echo "wrote $i 200k files"
10800         sync
10801         sleep_maxage
10802
10803         echo "Note: free space may not be updated, so measurements might be off"
10804         free_min_max
10805         DIFF2=$((MAXV - MINV))
10806         echo "free space delta: orig $DIFF final $DIFF2"
10807         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10808         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10809         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10810         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10811         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10812         if [[ $DIFF -gt 0 ]]; then
10813                 FILL=$((DIFF2 * 100 / DIFF - 100))
10814                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10815         fi
10816
10817         # Figure out which files were written where
10818         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10819                awk '/'$MINI1': / {print $2; exit}')
10820         echo $UUID
10821         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10822         echo "$MINC files created on smaller OST $MINI1"
10823         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10824                awk '/'$MAXI1': / {print $2; exit}')
10825         echo $UUID
10826         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10827         echo "$MAXC files created on larger OST $MAXI1"
10828         if [[ $MINC -gt 0 ]]; then
10829                 FILL=$((MAXC * 100 / MINC - 100))
10830                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10831         fi
10832         [[ $MAXC -gt $MINC ]] ||
10833                 error_ignore LU-9 "stripe QOS didn't balance free space"
10834         simple_cleanup_common
10835 }
10836 run_test 116a "stripe QOS: free space balance ==================="
10837
10838 test_116b() { # LU-2093
10839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10840         remote_mds_nodsh && skip "remote MDS with nodsh"
10841
10842 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10843         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10844                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10845         [ -z "$old_rr" ] && skip "no QOS"
10846         do_facet $SINGLEMDS lctl set_param \
10847                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10848         mkdir -p $DIR/$tdir
10849         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10850         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10851         do_facet $SINGLEMDS lctl set_param fail_loc=0
10852         rm -rf $DIR/$tdir
10853         do_facet $SINGLEMDS lctl set_param \
10854                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10855 }
10856 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10857
10858 test_117() # bug 10891
10859 {
10860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10861
10862         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10863         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10864         lctl set_param fail_loc=0x21e
10865         > $DIR/$tfile || error "truncate failed"
10866         lctl set_param fail_loc=0
10867         echo "Truncate succeeded."
10868         rm -f $DIR/$tfile
10869 }
10870 run_test 117 "verify osd extend =========="
10871
10872 NO_SLOW_RESENDCOUNT=4
10873 export OLD_RESENDCOUNT=""
10874 set_resend_count () {
10875         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10876         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10877         lctl set_param -n $PROC_RESENDCOUNT $1
10878         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10879 }
10880
10881 # for reduce test_118* time (b=14842)
10882 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10883
10884 # Reset async IO behavior after error case
10885 reset_async() {
10886         FILE=$DIR/reset_async
10887
10888         # Ensure all OSCs are cleared
10889         $LFS setstripe -c -1 $FILE
10890         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10891         sync
10892         rm $FILE
10893 }
10894
10895 test_118a() #bug 11710
10896 {
10897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10898
10899         reset_async
10900
10901         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10902         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10903         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10904
10905         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10906                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10907                 return 1;
10908         fi
10909         rm -f $DIR/$tfile
10910 }
10911 run_test 118a "verify O_SYNC works =========="
10912
10913 test_118b()
10914 {
10915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10916         remote_ost_nodsh && skip "remote OST with nodsh"
10917
10918         reset_async
10919
10920         #define OBD_FAIL_SRV_ENOENT 0x217
10921         set_nodes_failloc "$(osts_nodes)" 0x217
10922         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10923         RC=$?
10924         set_nodes_failloc "$(osts_nodes)" 0
10925         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10926         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10927                     grep -c writeback)
10928
10929         if [[ $RC -eq 0 ]]; then
10930                 error "Must return error due to dropped pages, rc=$RC"
10931                 return 1;
10932         fi
10933
10934         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10935                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10936                 return 1;
10937         fi
10938
10939         echo "Dirty pages not leaked on ENOENT"
10940
10941         # Due to the above error the OSC will issue all RPCs syncronously
10942         # until a subsequent RPC completes successfully without error.
10943         $MULTIOP $DIR/$tfile Ow4096yc
10944         rm -f $DIR/$tfile
10945
10946         return 0
10947 }
10948 run_test 118b "Reclaim dirty pages on fatal error =========="
10949
10950 test_118c()
10951 {
10952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10953
10954         # for 118c, restore the original resend count, LU-1940
10955         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10956                                 set_resend_count $OLD_RESENDCOUNT
10957         remote_ost_nodsh && skip "remote OST with nodsh"
10958
10959         reset_async
10960
10961         #define OBD_FAIL_OST_EROFS               0x216
10962         set_nodes_failloc "$(osts_nodes)" 0x216
10963
10964         # multiop should block due to fsync until pages are written
10965         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10966         MULTIPID=$!
10967         sleep 1
10968
10969         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10970                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10971         fi
10972
10973         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10974                     grep -c writeback)
10975         if [[ $WRITEBACK -eq 0 ]]; then
10976                 error "No page in writeback, writeback=$WRITEBACK"
10977         fi
10978
10979         set_nodes_failloc "$(osts_nodes)" 0
10980         wait $MULTIPID
10981         RC=$?
10982         if [[ $RC -ne 0 ]]; then
10983                 error "Multiop fsync failed, rc=$RC"
10984         fi
10985
10986         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10987         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10988                     grep -c writeback)
10989         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10990                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10991         fi
10992
10993         rm -f $DIR/$tfile
10994         echo "Dirty pages flushed via fsync on EROFS"
10995         return 0
10996 }
10997 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10998
10999 # continue to use small resend count to reduce test_118* time (b=14842)
11000 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11001
11002 test_118d()
11003 {
11004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11005         remote_ost_nodsh && skip "remote OST with nodsh"
11006
11007         reset_async
11008
11009         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11010         set_nodes_failloc "$(osts_nodes)" 0x214
11011         # multiop should block due to fsync until pages are written
11012         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11013         MULTIPID=$!
11014         sleep 1
11015
11016         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11017                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11018         fi
11019
11020         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11021                     grep -c writeback)
11022         if [[ $WRITEBACK -eq 0 ]]; then
11023                 error "No page in writeback, writeback=$WRITEBACK"
11024         fi
11025
11026         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11027         set_nodes_failloc "$(osts_nodes)" 0
11028
11029         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11030         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11031                     grep -c writeback)
11032         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11033                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11034         fi
11035
11036         rm -f $DIR/$tfile
11037         echo "Dirty pages gaurenteed flushed via fsync"
11038         return 0
11039 }
11040 run_test 118d "Fsync validation inject a delay of the bulk =========="
11041
11042 test_118f() {
11043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11044
11045         reset_async
11046
11047         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11048         lctl set_param fail_loc=0x8000040a
11049
11050         # Should simulate EINVAL error which is fatal
11051         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11052         RC=$?
11053         if [[ $RC -eq 0 ]]; then
11054                 error "Must return error due to dropped pages, rc=$RC"
11055         fi
11056
11057         lctl set_param fail_loc=0x0
11058
11059         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11060         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11061         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11062                     grep -c writeback)
11063         if [[ $LOCKED -ne 0 ]]; then
11064                 error "Locked pages remain in cache, locked=$LOCKED"
11065         fi
11066
11067         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11068                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11069         fi
11070
11071         rm -f $DIR/$tfile
11072         echo "No pages locked after fsync"
11073
11074         reset_async
11075         return 0
11076 }
11077 run_test 118f "Simulate unrecoverable OSC side error =========="
11078
11079 test_118g() {
11080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11081
11082         reset_async
11083
11084         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11085         lctl set_param fail_loc=0x406
11086
11087         # simulate local -ENOMEM
11088         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11089         RC=$?
11090
11091         lctl set_param fail_loc=0
11092         if [[ $RC -eq 0 ]]; then
11093                 error "Must return error due to dropped pages, rc=$RC"
11094         fi
11095
11096         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11097         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11098         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11099                         grep -c writeback)
11100         if [[ $LOCKED -ne 0 ]]; then
11101                 error "Locked pages remain in cache, locked=$LOCKED"
11102         fi
11103
11104         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11105                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11106         fi
11107
11108         rm -f $DIR/$tfile
11109         echo "No pages locked after fsync"
11110
11111         reset_async
11112         return 0
11113 }
11114 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11115
11116 test_118h() {
11117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11118         remote_ost_nodsh && skip "remote OST with nodsh"
11119
11120         reset_async
11121
11122         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11123         set_nodes_failloc "$(osts_nodes)" 0x20e
11124         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11125         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11126         RC=$?
11127
11128         set_nodes_failloc "$(osts_nodes)" 0
11129         if [[ $RC -eq 0 ]]; then
11130                 error "Must return error due to dropped pages, rc=$RC"
11131         fi
11132
11133         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11134         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11135         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11136                     grep -c writeback)
11137         if [[ $LOCKED -ne 0 ]]; then
11138                 error "Locked pages remain in cache, locked=$LOCKED"
11139         fi
11140
11141         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11142                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11143         fi
11144
11145         rm -f $DIR/$tfile
11146         echo "No pages locked after fsync"
11147
11148         return 0
11149 }
11150 run_test 118h "Verify timeout in handling recoverables errors  =========="
11151
11152 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11153
11154 test_118i() {
11155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11156         remote_ost_nodsh && skip "remote OST with nodsh"
11157
11158         reset_async
11159
11160         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11161         set_nodes_failloc "$(osts_nodes)" 0x20e
11162
11163         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11164         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11165         PID=$!
11166         sleep 5
11167         set_nodes_failloc "$(osts_nodes)" 0
11168
11169         wait $PID
11170         RC=$?
11171         if [[ $RC -ne 0 ]]; then
11172                 error "got error, but should be not, rc=$RC"
11173         fi
11174
11175         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11176         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11177         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11178         if [[ $LOCKED -ne 0 ]]; then
11179                 error "Locked pages remain in cache, locked=$LOCKED"
11180         fi
11181
11182         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11183                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11184         fi
11185
11186         rm -f $DIR/$tfile
11187         echo "No pages locked after fsync"
11188
11189         return 0
11190 }
11191 run_test 118i "Fix error before timeout in recoverable error  =========="
11192
11193 [ "$SLOW" = "no" ] && set_resend_count 4
11194
11195 test_118j() {
11196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11197         remote_ost_nodsh && skip "remote OST with nodsh"
11198
11199         reset_async
11200
11201         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11202         set_nodes_failloc "$(osts_nodes)" 0x220
11203
11204         # return -EIO from OST
11205         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11206         RC=$?
11207         set_nodes_failloc "$(osts_nodes)" 0x0
11208         if [[ $RC -eq 0 ]]; then
11209                 error "Must return error due to dropped pages, rc=$RC"
11210         fi
11211
11212         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11213         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11214         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11215         if [[ $LOCKED -ne 0 ]]; then
11216                 error "Locked pages remain in cache, locked=$LOCKED"
11217         fi
11218
11219         # in recoverable error on OST we want resend and stay until it finished
11220         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11221                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11222         fi
11223
11224         rm -f $DIR/$tfile
11225         echo "No pages locked after fsync"
11226
11227         return 0
11228 }
11229 run_test 118j "Simulate unrecoverable OST side error =========="
11230
11231 test_118k()
11232 {
11233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11234         remote_ost_nodsh && skip "remote OSTs with nodsh"
11235
11236         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11237         set_nodes_failloc "$(osts_nodes)" 0x20e
11238         test_mkdir $DIR/$tdir
11239
11240         for ((i=0;i<10;i++)); do
11241                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11242                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11243                 SLEEPPID=$!
11244                 sleep 0.500s
11245                 kill $SLEEPPID
11246                 wait $SLEEPPID
11247         done
11248
11249         set_nodes_failloc "$(osts_nodes)" 0
11250         rm -rf $DIR/$tdir
11251 }
11252 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11253
11254 test_118l() # LU-646
11255 {
11256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11257
11258         test_mkdir $DIR/$tdir
11259         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11260         rm -rf $DIR/$tdir
11261 }
11262 run_test 118l "fsync dir"
11263
11264 test_118m() # LU-3066
11265 {
11266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11267
11268         test_mkdir $DIR/$tdir
11269         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11270         rm -rf $DIR/$tdir
11271 }
11272 run_test 118m "fdatasync dir ========="
11273
11274 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11275
11276 test_118n()
11277 {
11278         local begin
11279         local end
11280
11281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11282         remote_ost_nodsh && skip "remote OSTs with nodsh"
11283
11284         # Sleep to avoid a cached response.
11285         #define OBD_STATFS_CACHE_SECONDS 1
11286         sleep 2
11287
11288         # Inject a 10 second delay in the OST_STATFS handler.
11289         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11290         set_nodes_failloc "$(osts_nodes)" 0x242
11291
11292         begin=$SECONDS
11293         stat --file-system $MOUNT > /dev/null
11294         end=$SECONDS
11295
11296         set_nodes_failloc "$(osts_nodes)" 0
11297
11298         if ((end - begin > 20)); then
11299             error "statfs took $((end - begin)) seconds, expected 10"
11300         fi
11301 }
11302 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11303
11304 test_119a() # bug 11737
11305 {
11306         BSIZE=$((512 * 1024))
11307         directio write $DIR/$tfile 0 1 $BSIZE
11308         # We ask to read two blocks, which is more than a file size.
11309         # directio will indicate an error when requested and actual
11310         # sizes aren't equeal (a normal situation in this case) and
11311         # print actual read amount.
11312         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11313         if [ "$NOB" != "$BSIZE" ]; then
11314                 error "read $NOB bytes instead of $BSIZE"
11315         fi
11316         rm -f $DIR/$tfile
11317 }
11318 run_test 119a "Short directIO read must return actual read amount"
11319
11320 test_119b() # bug 11737
11321 {
11322         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11323
11324         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11325         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11326         sync
11327         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11328                 error "direct read failed"
11329         rm -f $DIR/$tfile
11330 }
11331 run_test 119b "Sparse directIO read must return actual read amount"
11332
11333 test_119c() # bug 13099
11334 {
11335         BSIZE=1048576
11336         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11337         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11338         rm -f $DIR/$tfile
11339 }
11340 run_test 119c "Testing for direct read hitting hole"
11341
11342 test_119d() # bug 15950
11343 {
11344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11345
11346         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11347         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11348         BSIZE=1048576
11349         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11350         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11351         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11352         lctl set_param fail_loc=0x40d
11353         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11354         pid_dio=$!
11355         sleep 1
11356         cat $DIR/$tfile > /dev/null &
11357         lctl set_param fail_loc=0
11358         pid_reads=$!
11359         wait $pid_dio
11360         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11361         sleep 2
11362         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11363         error "the read rpcs have not completed in 2s"
11364         rm -f $DIR/$tfile
11365         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11366 }
11367 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11368
11369 test_120a() {
11370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11371         remote_mds_nodsh && skip "remote MDS with nodsh"
11372         test_mkdir -i0 -c1 $DIR/$tdir
11373         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11374                 skip_env "no early lock cancel on server"
11375
11376         lru_resize_disable mdc
11377         lru_resize_disable osc
11378         cancel_lru_locks mdc
11379         # asynchronous object destroy at MDT could cause bl ast to client
11380         cancel_lru_locks osc
11381
11382         stat $DIR/$tdir > /dev/null
11383         can1=$(do_facet mds1 \
11384                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11385                awk '/ldlm_cancel/ {print $2}')
11386         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11387                awk '/ldlm_bl_callback/ {print $2}')
11388         test_mkdir -i0 -c1 $DIR/$tdir/d1
11389         can2=$(do_facet mds1 \
11390                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11391                awk '/ldlm_cancel/ {print $2}')
11392         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11393                awk '/ldlm_bl_callback/ {print $2}')
11394         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11395         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11396         lru_resize_enable mdc
11397         lru_resize_enable osc
11398 }
11399 run_test 120a "Early Lock Cancel: mkdir test"
11400
11401 test_120b() {
11402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11403         remote_mds_nodsh && skip "remote MDS with nodsh"
11404         test_mkdir $DIR/$tdir
11405         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11406                 skip_env "no early lock cancel on server"
11407
11408         lru_resize_disable mdc
11409         lru_resize_disable osc
11410         cancel_lru_locks mdc
11411         stat $DIR/$tdir > /dev/null
11412         can1=$(do_facet $SINGLEMDS \
11413                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11414                awk '/ldlm_cancel/ {print $2}')
11415         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11416                awk '/ldlm_bl_callback/ {print $2}')
11417         touch $DIR/$tdir/f1
11418         can2=$(do_facet $SINGLEMDS \
11419                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11420                awk '/ldlm_cancel/ {print $2}')
11421         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11422                awk '/ldlm_bl_callback/ {print $2}')
11423         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11424         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11425         lru_resize_enable mdc
11426         lru_resize_enable osc
11427 }
11428 run_test 120b "Early Lock Cancel: create test"
11429
11430 test_120c() {
11431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11432         remote_mds_nodsh && skip "remote MDS with nodsh"
11433         test_mkdir -i0 -c1 $DIR/$tdir
11434         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11435                 skip "no early lock cancel on server"
11436
11437         lru_resize_disable mdc
11438         lru_resize_disable osc
11439         test_mkdir -i0 -c1 $DIR/$tdir/d1
11440         test_mkdir -i0 -c1 $DIR/$tdir/d2
11441         touch $DIR/$tdir/d1/f1
11442         cancel_lru_locks mdc
11443         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11444         can1=$(do_facet mds1 \
11445                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11446                awk '/ldlm_cancel/ {print $2}')
11447         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11448                awk '/ldlm_bl_callback/ {print $2}')
11449         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11450         can2=$(do_facet mds1 \
11451                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11452                awk '/ldlm_cancel/ {print $2}')
11453         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11454                awk '/ldlm_bl_callback/ {print $2}')
11455         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11456         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11457         lru_resize_enable mdc
11458         lru_resize_enable osc
11459 }
11460 run_test 120c "Early Lock Cancel: link test"
11461
11462 test_120d() {
11463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11464         remote_mds_nodsh && skip "remote MDS with nodsh"
11465         test_mkdir -i0 -c1 $DIR/$tdir
11466         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11467                 skip_env "no early lock cancel on server"
11468
11469         lru_resize_disable mdc
11470         lru_resize_disable osc
11471         touch $DIR/$tdir
11472         cancel_lru_locks mdc
11473         stat $DIR/$tdir > /dev/null
11474         can1=$(do_facet mds1 \
11475                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11476                awk '/ldlm_cancel/ {print $2}')
11477         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11478                awk '/ldlm_bl_callback/ {print $2}')
11479         chmod a+x $DIR/$tdir
11480         can2=$(do_facet mds1 \
11481                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11482                awk '/ldlm_cancel/ {print $2}')
11483         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11484                awk '/ldlm_bl_callback/ {print $2}')
11485         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11486         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11487         lru_resize_enable mdc
11488         lru_resize_enable osc
11489 }
11490 run_test 120d "Early Lock Cancel: setattr test"
11491
11492 test_120e() {
11493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11494         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11495                 skip_env "no early lock cancel on server"
11496         remote_mds_nodsh && skip "remote MDS with nodsh"
11497
11498         local dlmtrace_set=false
11499
11500         test_mkdir -i0 -c1 $DIR/$tdir
11501         lru_resize_disable mdc
11502         lru_resize_disable osc
11503         ! $LCTL get_param debug | grep -q dlmtrace &&
11504                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11505         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11506         cancel_lru_locks mdc
11507         cancel_lru_locks osc
11508         dd if=$DIR/$tdir/f1 of=/dev/null
11509         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11510         # XXX client can not do early lock cancel of OST lock
11511         # during unlink (LU-4206), so cancel osc lock now.
11512         sleep 2
11513         cancel_lru_locks osc
11514         can1=$(do_facet mds1 \
11515                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11516                awk '/ldlm_cancel/ {print $2}')
11517         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11518                awk '/ldlm_bl_callback/ {print $2}')
11519         unlink $DIR/$tdir/f1
11520         sleep 5
11521         can2=$(do_facet mds1 \
11522                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11523                awk '/ldlm_cancel/ {print $2}')
11524         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11525                awk '/ldlm_bl_callback/ {print $2}')
11526         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11527                 $LCTL dk $TMP/cancel.debug.txt
11528         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11529                 $LCTL dk $TMP/blocking.debug.txt
11530         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11531         lru_resize_enable mdc
11532         lru_resize_enable osc
11533 }
11534 run_test 120e "Early Lock Cancel: unlink test"
11535
11536 test_120f() {
11537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11538         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11539                 skip_env "no early lock cancel on server"
11540         remote_mds_nodsh && skip "remote MDS with nodsh"
11541
11542         test_mkdir -i0 -c1 $DIR/$tdir
11543         lru_resize_disable mdc
11544         lru_resize_disable osc
11545         test_mkdir -i0 -c1 $DIR/$tdir/d1
11546         test_mkdir -i0 -c1 $DIR/$tdir/d2
11547         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11548         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11549         cancel_lru_locks mdc
11550         cancel_lru_locks osc
11551         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11552         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11553         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11554         # XXX client can not do early lock cancel of OST lock
11555         # during rename (LU-4206), so cancel osc lock now.
11556         sleep 2
11557         cancel_lru_locks osc
11558         can1=$(do_facet mds1 \
11559                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11560                awk '/ldlm_cancel/ {print $2}')
11561         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11562                awk '/ldlm_bl_callback/ {print $2}')
11563         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11564         sleep 5
11565         can2=$(do_facet mds1 \
11566                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11567                awk '/ldlm_cancel/ {print $2}')
11568         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11569                awk '/ldlm_bl_callback/ {print $2}')
11570         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11571         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11572         lru_resize_enable mdc
11573         lru_resize_enable osc
11574 }
11575 run_test 120f "Early Lock Cancel: rename test"
11576
11577 test_120g() {
11578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11579         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11580                 skip_env "no early lock cancel on server"
11581         remote_mds_nodsh && skip "remote MDS with nodsh"
11582
11583         lru_resize_disable mdc
11584         lru_resize_disable osc
11585         count=10000
11586         echo create $count files
11587         test_mkdir $DIR/$tdir
11588         cancel_lru_locks mdc
11589         cancel_lru_locks osc
11590         t0=$(date +%s)
11591
11592         can0=$(do_facet $SINGLEMDS \
11593                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11594                awk '/ldlm_cancel/ {print $2}')
11595         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11596                awk '/ldlm_bl_callback/ {print $2}')
11597         createmany -o $DIR/$tdir/f $count
11598         sync
11599         can1=$(do_facet $SINGLEMDS \
11600                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11601                awk '/ldlm_cancel/ {print $2}')
11602         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11603                awk '/ldlm_bl_callback/ {print $2}')
11604         t1=$(date +%s)
11605         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11606         echo rm $count files
11607         rm -r $DIR/$tdir
11608         sync
11609         can2=$(do_facet $SINGLEMDS \
11610                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11611                awk '/ldlm_cancel/ {print $2}')
11612         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11613                awk '/ldlm_bl_callback/ {print $2}')
11614         t2=$(date +%s)
11615         echo total: $count removes in $((t2-t1))
11616         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11617         sleep 2
11618         # wait for commitment of removal
11619         lru_resize_enable mdc
11620         lru_resize_enable osc
11621 }
11622 run_test 120g "Early Lock Cancel: performance test"
11623
11624 test_121() { #bug #10589
11625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11626
11627         rm -rf $DIR/$tfile
11628         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11629 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11630         lctl set_param fail_loc=0x310
11631         cancel_lru_locks osc > /dev/null
11632         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11633         lctl set_param fail_loc=0
11634         [[ $reads -eq $writes ]] ||
11635                 error "read $reads blocks, must be $writes blocks"
11636 }
11637 run_test 121 "read cancel race ========="
11638
11639 test_123a_base() { # was test 123, statahead(bug 11401)
11640         local lsx="$1"
11641
11642         SLOWOK=0
11643         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11644                 log "testing UP system. Performance may be lower than expected."
11645                 SLOWOK=1
11646         fi
11647
11648         rm -rf $DIR/$tdir
11649         test_mkdir $DIR/$tdir
11650         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11651         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11652         MULT=10
11653         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11654                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11655
11656                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11657                 lctl set_param -n llite.*.statahead_max 0
11658                 lctl get_param llite.*.statahead_max
11659                 cancel_lru_locks mdc
11660                 cancel_lru_locks osc
11661                 stime=$(date +%s)
11662                 time $lsx $DIR/$tdir | wc -l
11663                 etime=$(date +%s)
11664                 delta=$((etime - stime))
11665                 log "$lsx $i files without statahead: $delta sec"
11666                 lctl set_param llite.*.statahead_max=$max
11667
11668                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11669                         grep "statahead wrong:" | awk '{print $3}')
11670                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11671                 cancel_lru_locks mdc
11672                 cancel_lru_locks osc
11673                 stime=$(date +%s)
11674                 time $lsx $DIR/$tdir | wc -l
11675                 etime=$(date +%s)
11676                 delta_sa=$((etime - stime))
11677                 log "$lsx $i files with statahead: $delta_sa sec"
11678                 lctl get_param -n llite.*.statahead_stats
11679                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11680                         grep "statahead wrong:" | awk '{print $3}')
11681
11682                 [[ $swrong -lt $ewrong ]] &&
11683                         log "statahead was stopped, maybe too many locks held!"
11684                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11685
11686                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11687                         max=$(lctl get_param -n llite.*.statahead_max |
11688                                 head -n 1)
11689                         lctl set_param -n llite.*.statahead_max 0
11690                         lctl get_param llite.*.statahead_max
11691                         cancel_lru_locks mdc
11692                         cancel_lru_locks osc
11693                         stime=$(date +%s)
11694                         time $lsx $DIR/$tdir | wc -l
11695                         etime=$(date +%s)
11696                         delta=$((etime - stime))
11697                         log "$lsx $i files again without statahead: $delta sec"
11698                         lctl set_param llite.*.statahead_max=$max
11699                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11700                                 if [  $SLOWOK -eq 0 ]; then
11701                                         error "$lsx $i files is slower with statahead!"
11702                                 else
11703                                         log "$lsx $i files is slower with statahead!"
11704                                 fi
11705                                 break
11706                         fi
11707                 fi
11708
11709                 [ $delta -gt 20 ] && break
11710                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11711                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11712         done
11713         log "$lsx done"
11714
11715         stime=$(date +%s)
11716         rm -r $DIR/$tdir
11717         sync
11718         etime=$(date +%s)
11719         delta=$((etime - stime))
11720         log "rm -r $DIR/$tdir/: $delta seconds"
11721         log "rm done"
11722         lctl get_param -n llite.*.statahead_stats
11723 }
11724
11725 test_123aa() {
11726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11727
11728         test_123a_base "ls -l"
11729 }
11730 run_test 123aa "verify statahead work"
11731
11732 test_123ab() {
11733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11734
11735         statx_supported || skip_env "Test must be statx() syscall supported"
11736
11737         test_123a_base "$STATX -l"
11738 }
11739 run_test 123ab "verify statahead work by using statx"
11740
11741 test_123ac() {
11742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11743
11744         statx_supported || skip_env "Test must be statx() syscall supported"
11745
11746         local rpcs_before
11747         local rpcs_after
11748         local agl_before
11749         local agl_after
11750
11751         cancel_lru_locks $OSC
11752         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11753         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11754                 awk '/agl.total:/ {print $3}')
11755         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11756         test_123a_base "$STATX --cached=always -D"
11757         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11758                 awk '/agl.total:/ {print $3}')
11759         [ $agl_before -eq $agl_after ] ||
11760                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11761         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11762         [ $rpcs_after -eq $rpcs_before ] ||
11763                 error "$STATX should not send glimpse RPCs to $OSC"
11764 }
11765 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11766
11767 test_123b () { # statahead(bug 15027)
11768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11769
11770         test_mkdir $DIR/$tdir
11771         createmany -o $DIR/$tdir/$tfile-%d 1000
11772
11773         cancel_lru_locks mdc
11774         cancel_lru_locks osc
11775
11776 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11777         lctl set_param fail_loc=0x80000803
11778         ls -lR $DIR/$tdir > /dev/null
11779         log "ls done"
11780         lctl set_param fail_loc=0x0
11781         lctl get_param -n llite.*.statahead_stats
11782         rm -r $DIR/$tdir
11783         sync
11784
11785 }
11786 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11787
11788 test_123c() {
11789         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11790
11791         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11792         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11793         touch $DIR/$tdir.1/{1..3}
11794         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11795
11796         remount_client $MOUNT
11797
11798         $MULTIOP $DIR/$tdir.0 Q
11799
11800         # let statahead to complete
11801         ls -l $DIR/$tdir.0 > /dev/null
11802
11803         testid=$(echo $TESTNAME | tr '_' ' ')
11804         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11805                 error "statahead warning" || true
11806 }
11807 run_test 123c "Can not initialize inode warning on DNE statahead"
11808
11809 test_124a() {
11810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11811         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11812                 skip_env "no lru resize on server"
11813
11814         local NR=2000
11815
11816         test_mkdir $DIR/$tdir
11817
11818         log "create $NR files at $DIR/$tdir"
11819         createmany -o $DIR/$tdir/f $NR ||
11820                 error "failed to create $NR files in $DIR/$tdir"
11821
11822         cancel_lru_locks mdc
11823         ls -l $DIR/$tdir > /dev/null
11824
11825         local NSDIR=""
11826         local LRU_SIZE=0
11827         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11828                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11829                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11830                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11831                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11832                         log "NSDIR=$NSDIR"
11833                         log "NS=$(basename $NSDIR)"
11834                         break
11835                 fi
11836         done
11837
11838         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11839                 skip "Not enough cached locks created!"
11840         fi
11841         log "LRU=$LRU_SIZE"
11842
11843         local SLEEP=30
11844
11845         # We know that lru resize allows one client to hold $LIMIT locks
11846         # for 10h. After that locks begin to be killed by client.
11847         local MAX_HRS=10
11848         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11849         log "LIMIT=$LIMIT"
11850         if [ $LIMIT -lt $LRU_SIZE ]; then
11851                 skip "Limit is too small $LIMIT"
11852         fi
11853
11854         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11855         # killing locks. Some time was spent for creating locks. This means
11856         # that up to the moment of sleep finish we must have killed some of
11857         # them (10-100 locks). This depends on how fast ther were created.
11858         # Many of them were touched in almost the same moment and thus will
11859         # be killed in groups.
11860         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11861
11862         # Use $LRU_SIZE_B here to take into account real number of locks
11863         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11864         local LRU_SIZE_B=$LRU_SIZE
11865         log "LVF=$LVF"
11866         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11867         log "OLD_LVF=$OLD_LVF"
11868         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11869
11870         # Let's make sure that we really have some margin. Client checks
11871         # cached locks every 10 sec.
11872         SLEEP=$((SLEEP+20))
11873         log "Sleep ${SLEEP} sec"
11874         local SEC=0
11875         while ((SEC<$SLEEP)); do
11876                 echo -n "..."
11877                 sleep 5
11878                 SEC=$((SEC+5))
11879                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11880                 echo -n "$LRU_SIZE"
11881         done
11882         echo ""
11883         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11884         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11885
11886         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11887                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11888                 unlinkmany $DIR/$tdir/f $NR
11889                 return
11890         }
11891
11892         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11893         log "unlink $NR files at $DIR/$tdir"
11894         unlinkmany $DIR/$tdir/f $NR
11895 }
11896 run_test 124a "lru resize ======================================="
11897
11898 get_max_pool_limit()
11899 {
11900         local limit=$($LCTL get_param \
11901                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11902         local max=0
11903         for l in $limit; do
11904                 if [[ $l -gt $max ]]; then
11905                         max=$l
11906                 fi
11907         done
11908         echo $max
11909 }
11910
11911 test_124b() {
11912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11913         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11914                 skip_env "no lru resize on server"
11915
11916         LIMIT=$(get_max_pool_limit)
11917
11918         NR=$(($(default_lru_size)*20))
11919         if [[ $NR -gt $LIMIT ]]; then
11920                 log "Limit lock number by $LIMIT locks"
11921                 NR=$LIMIT
11922         fi
11923
11924         IFree=$(mdsrate_inodes_available)
11925         if [ $IFree -lt $NR ]; then
11926                 log "Limit lock number by $IFree inodes"
11927                 NR=$IFree
11928         fi
11929
11930         lru_resize_disable mdc
11931         test_mkdir -p $DIR/$tdir/disable_lru_resize
11932
11933         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11934         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11935         cancel_lru_locks mdc
11936         stime=`date +%s`
11937         PID=""
11938         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11939         PID="$PID $!"
11940         sleep 2
11941         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11942         PID="$PID $!"
11943         sleep 2
11944         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11945         PID="$PID $!"
11946         wait $PID
11947         etime=`date +%s`
11948         nolruresize_delta=$((etime-stime))
11949         log "ls -la time: $nolruresize_delta seconds"
11950         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11951         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11952
11953         lru_resize_enable mdc
11954         test_mkdir -p $DIR/$tdir/enable_lru_resize
11955
11956         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11957         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11958         cancel_lru_locks mdc
11959         stime=`date +%s`
11960         PID=""
11961         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11962         PID="$PID $!"
11963         sleep 2
11964         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11965         PID="$PID $!"
11966         sleep 2
11967         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11968         PID="$PID $!"
11969         wait $PID
11970         etime=`date +%s`
11971         lruresize_delta=$((etime-stime))
11972         log "ls -la time: $lruresize_delta seconds"
11973         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11974
11975         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11976                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11977         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11978                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11979         else
11980                 log "lru resize performs the same with no lru resize"
11981         fi
11982         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11983 }
11984 run_test 124b "lru resize (performance test) ======================="
11985
11986 test_124c() {
11987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11988         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11989                 skip_env "no lru resize on server"
11990
11991         # cache ununsed locks on client
11992         local nr=100
11993         cancel_lru_locks mdc
11994         test_mkdir $DIR/$tdir
11995         createmany -o $DIR/$tdir/f $nr ||
11996                 error "failed to create $nr files in $DIR/$tdir"
11997         ls -l $DIR/$tdir > /dev/null
11998
11999         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12000         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12001         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12002         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12003         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12004
12005         # set lru_max_age to 1 sec
12006         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12007         echo "sleep $((recalc_p * 2)) seconds..."
12008         sleep $((recalc_p * 2))
12009
12010         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12011         # restore lru_max_age
12012         $LCTL set_param -n $nsdir.lru_max_age $max_age
12013         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12014         unlinkmany $DIR/$tdir/f $nr
12015 }
12016 run_test 124c "LRUR cancel very aged locks"
12017
12018 test_124d() {
12019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12020         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12021                 skip_env "no lru resize on server"
12022
12023         # cache ununsed locks on client
12024         local nr=100
12025
12026         lru_resize_disable mdc
12027         stack_trap "lru_resize_enable mdc" EXIT
12028
12029         cancel_lru_locks mdc
12030
12031         # asynchronous object destroy at MDT could cause bl ast to client
12032         test_mkdir $DIR/$tdir
12033         createmany -o $DIR/$tdir/f $nr ||
12034                 error "failed to create $nr files in $DIR/$tdir"
12035         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12036
12037         ls -l $DIR/$tdir > /dev/null
12038
12039         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12040         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12041         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12042         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12043
12044         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12045
12046         # set lru_max_age to 1 sec
12047         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12048         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12049
12050         echo "sleep $((recalc_p * 2)) seconds..."
12051         sleep $((recalc_p * 2))
12052
12053         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12054
12055         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12056 }
12057 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12058
12059 test_125() { # 13358
12060         $LCTL get_param -n llite.*.client_type | grep -q local ||
12061                 skip "must run as local client"
12062         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12063                 skip_env "must have acl enabled"
12064         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12065
12066         test_mkdir $DIR/$tdir
12067         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12068         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12069         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12070 }
12071 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12072
12073 test_126() { # bug 12829/13455
12074         $GSS && skip_env "must run as gss disabled"
12075         $LCTL get_param -n llite.*.client_type | grep -q local ||
12076                 skip "must run as local client"
12077         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12078
12079         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12080         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12081         rm -f $DIR/$tfile
12082         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12083 }
12084 run_test 126 "check that the fsgid provided by the client is taken into account"
12085
12086 test_127a() { # bug 15521
12087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12088         local name count samp unit min max sum sumsq
12089
12090         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12091         echo "stats before reset"
12092         $LCTL get_param osc.*.stats
12093         $LCTL set_param osc.*.stats=0
12094         local fsize=$((2048 * 1024))
12095
12096         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12097         cancel_lru_locks osc
12098         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12099
12100         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12101         stack_trap "rm -f $TMP/$tfile.tmp"
12102         while read name count samp unit min max sum sumsq; do
12103                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12104                 [ ! $min ] && error "Missing min value for $name proc entry"
12105                 eval $name=$count || error "Wrong proc format"
12106
12107                 case $name in
12108                 read_bytes|write_bytes)
12109                         [[ "$unit" =~ "bytes" ]] ||
12110                                 error "unit is not 'bytes': $unit"
12111                         (( $min >= 4096 )) || error "min is too small: $min"
12112                         (( $min <= $fsize )) || error "min is too big: $min"
12113                         (( $max >= 4096 )) || error "max is too small: $max"
12114                         (( $max <= $fsize )) || error "max is too big: $max"
12115                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12116                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12117                                 error "sumsquare is too small: $sumsq"
12118                         (( $sumsq <= $fsize * $fsize )) ||
12119                                 error "sumsquare is too big: $sumsq"
12120                         ;;
12121                 ost_read|ost_write)
12122                         [[ "$unit" =~ "usec" ]] ||
12123                                 error "unit is not 'usec': $unit"
12124                         ;;
12125                 *)      ;;
12126                 esac
12127         done < $DIR/$tfile.tmp
12128
12129         #check that we actually got some stats
12130         [ "$read_bytes" ] || error "Missing read_bytes stats"
12131         [ "$write_bytes" ] || error "Missing write_bytes stats"
12132         [ "$read_bytes" != 0 ] || error "no read done"
12133         [ "$write_bytes" != 0 ] || error "no write done"
12134 }
12135 run_test 127a "verify the client stats are sane"
12136
12137 test_127b() { # bug LU-333
12138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12139         local name count samp unit min max sum sumsq
12140
12141         echo "stats before reset"
12142         $LCTL get_param llite.*.stats
12143         $LCTL set_param llite.*.stats=0
12144
12145         # perform 2 reads and writes so MAX is different from SUM.
12146         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12147         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12148         cancel_lru_locks osc
12149         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12150         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12151
12152         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12153         stack_trap "rm -f $TMP/$tfile.tmp"
12154         while read name count samp unit min max sum sumsq; do
12155                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12156                 eval $name=$count || error "Wrong proc format"
12157
12158                 case $name in
12159                 read_bytes|write_bytes)
12160                         [[ "$unit" =~ "bytes" ]] ||
12161                                 error "unit is not 'bytes': $unit"
12162                         (( $count == 2 )) || error "count is not 2: $count"
12163                         (( $min == $PAGE_SIZE )) ||
12164                                 error "min is not $PAGE_SIZE: $min"
12165                         (( $max == $PAGE_SIZE )) ||
12166                                 error "max is not $PAGE_SIZE: $max"
12167                         (( $sum == $PAGE_SIZE * 2 )) ||
12168                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12169                         ;;
12170                 read|write)
12171                         [[ "$unit" =~ "usec" ]] ||
12172                                 error "unit is not 'usec': $unit"
12173                         ;;
12174                 *)      ;;
12175                 esac
12176         done < $TMP/$tfile.tmp
12177
12178         #check that we actually got some stats
12179         [ "$read_bytes" ] || error "Missing read_bytes stats"
12180         [ "$write_bytes" ] || error "Missing write_bytes stats"
12181         [ "$read_bytes" != 0 ] || error "no read done"
12182         [ "$write_bytes" != 0 ] || error "no write done"
12183 }
12184 run_test 127b "verify the llite client stats are sane"
12185
12186 test_127c() { # LU-12394
12187         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12188         local size
12189         local bsize
12190         local reads
12191         local writes
12192         local count
12193
12194         $LCTL set_param llite.*.extents_stats=1
12195         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12196
12197         # Use two stripes so there is enough space in default config
12198         $LFS setstripe -c 2 $DIR/$tfile
12199
12200         # Extent stats start at 0-4K and go in power of two buckets
12201         # LL_HIST_START = 12 --> 2^12 = 4K
12202         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12203         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12204         # small configs
12205         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12206                 do
12207                 # Write and read, 2x each, second time at a non-zero offset
12208                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12209                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12210                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12211                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12212                 rm -f $DIR/$tfile
12213         done
12214
12215         $LCTL get_param llite.*.extents_stats
12216
12217         count=2
12218         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12219                 do
12220                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12221                                 grep -m 1 $bsize)
12222                 reads=$(echo $bucket | awk '{print $5}')
12223                 writes=$(echo $bucket | awk '{print $9}')
12224                 [ "$reads" -eq $count ] ||
12225                         error "$reads reads in < $bsize bucket, expect $count"
12226                 [ "$writes" -eq $count ] ||
12227                         error "$writes writes in < $bsize bucket, expect $count"
12228         done
12229
12230         # Test mmap write and read
12231         $LCTL set_param llite.*.extents_stats=c
12232         size=512
12233         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12234         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12235         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12236
12237         $LCTL get_param llite.*.extents_stats
12238
12239         count=$(((size*1024) / PAGE_SIZE))
12240
12241         bsize=$((2 * PAGE_SIZE / 1024))K
12242
12243         bucket=$($LCTL get_param -n llite.*.extents_stats |
12244                         grep -m 1 $bsize)
12245         reads=$(echo $bucket | awk '{print $5}')
12246         writes=$(echo $bucket | awk '{print $9}')
12247         # mmap writes fault in the page first, creating an additonal read
12248         [ "$reads" -eq $((2 * count)) ] ||
12249                 error "$reads reads in < $bsize bucket, expect $count"
12250         [ "$writes" -eq $count ] ||
12251                 error "$writes writes in < $bsize bucket, expect $count"
12252 }
12253 run_test 127c "test llite extent stats with regular & mmap i/o"
12254
12255 test_128() { # bug 15212
12256         touch $DIR/$tfile
12257         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12258                 find $DIR/$tfile
12259                 find $DIR/$tfile
12260         EOF
12261
12262         result=$(grep error $TMP/$tfile.log)
12263         rm -f $DIR/$tfile $TMP/$tfile.log
12264         [ -z "$result" ] ||
12265                 error "consecutive find's under interactive lfs failed"
12266 }
12267 run_test 128 "interactive lfs for 2 consecutive find's"
12268
12269 set_dir_limits () {
12270         local mntdev
12271         local canondev
12272         local node
12273
12274         local ldproc=/proc/fs/ldiskfs
12275         local facets=$(get_facets MDS)
12276
12277         for facet in ${facets//,/ }; do
12278                 canondev=$(ldiskfs_canon \
12279                            *.$(convert_facet2label $facet).mntdev $facet)
12280                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12281                         ldproc=/sys/fs/ldiskfs
12282                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12283                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12284         done
12285 }
12286
12287 check_mds_dmesg() {
12288         local facets=$(get_facets MDS)
12289         for facet in ${facets//,/ }; do
12290                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12291         done
12292         return 1
12293 }
12294
12295 test_129() {
12296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12297         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12298                 skip "Need MDS version with at least 2.5.56"
12299         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12300                 skip_env "ldiskfs only test"
12301         fi
12302         remote_mds_nodsh && skip "remote MDS with nodsh"
12303
12304         local ENOSPC=28
12305         local has_warning=false
12306
12307         rm -rf $DIR/$tdir
12308         mkdir -p $DIR/$tdir
12309
12310         # block size of mds1
12311         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12312         set_dir_limits $maxsize $((maxsize * 6 / 8))
12313         stack_trap "set_dir_limits 0 0"
12314         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12315         local dirsize=$(stat -c%s "$DIR/$tdir")
12316         local nfiles=0
12317         while (( $dirsize <= $maxsize )); do
12318                 $MCREATE $DIR/$tdir/file_base_$nfiles
12319                 rc=$?
12320                 # check two errors:
12321                 # ENOSPC for ext4 max_dir_size, which has been used since
12322                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12323                 if (( rc == ENOSPC )); then
12324                         set_dir_limits 0 0
12325                         echo "rc=$rc returned as expected after $nfiles files"
12326
12327                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12328                                 error "create failed w/o dir size limit"
12329
12330                         # messages may be rate limited if test is run repeatedly
12331                         check_mds_dmesg '"is approaching max"' ||
12332                                 echo "warning message should be output"
12333                         check_mds_dmesg '"has reached max"' ||
12334                                 echo "reached message should be output"
12335
12336                         dirsize=$(stat -c%s "$DIR/$tdir")
12337
12338                         [[ $dirsize -ge $maxsize ]] && return 0
12339                         error "dirsize $dirsize < $maxsize after $nfiles files"
12340                 elif (( rc != 0 )); then
12341                         break
12342                 fi
12343                 nfiles=$((nfiles + 1))
12344                 dirsize=$(stat -c%s "$DIR/$tdir")
12345         done
12346
12347         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12348 }
12349 run_test 129 "test directory size limit ========================"
12350
12351 OLDIFS="$IFS"
12352 cleanup_130() {
12353         trap 0
12354         IFS="$OLDIFS"
12355 }
12356
12357 test_130a() {
12358         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12359         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12360
12361         trap cleanup_130 EXIT RETURN
12362
12363         local fm_file=$DIR/$tfile
12364         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12365         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12366                 error "dd failed for $fm_file"
12367
12368         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12369         filefrag -ves $fm_file
12370         RC=$?
12371         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12372                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12373         [ $RC != 0 ] && error "filefrag $fm_file failed"
12374
12375         filefrag_op=$(filefrag -ve -k $fm_file |
12376                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12377         lun=$($LFS getstripe -i $fm_file)
12378
12379         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12380         IFS=$'\n'
12381         tot_len=0
12382         for line in $filefrag_op
12383         do
12384                 frag_lun=`echo $line | cut -d: -f5`
12385                 ext_len=`echo $line | cut -d: -f4`
12386                 if (( $frag_lun != $lun )); then
12387                         cleanup_130
12388                         error "FIEMAP on 1-stripe file($fm_file) failed"
12389                         return
12390                 fi
12391                 (( tot_len += ext_len ))
12392         done
12393
12394         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12395                 cleanup_130
12396                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12397                 return
12398         fi
12399
12400         cleanup_130
12401
12402         echo "FIEMAP on single striped file succeeded"
12403 }
12404 run_test 130a "FIEMAP (1-stripe file)"
12405
12406 test_130b() {
12407         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12408
12409         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12410         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12411
12412         trap cleanup_130 EXIT RETURN
12413
12414         local fm_file=$DIR/$tfile
12415         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12416                         error "setstripe on $fm_file"
12417         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12418                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12419
12420         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12421                 error "dd failed on $fm_file"
12422
12423         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12424         filefrag_op=$(filefrag -ve -k $fm_file |
12425                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12426
12427         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12428                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12429
12430         IFS=$'\n'
12431         tot_len=0
12432         num_luns=1
12433         for line in $filefrag_op
12434         do
12435                 frag_lun=$(echo $line | cut -d: -f5 |
12436                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12437                 ext_len=$(echo $line | cut -d: -f4)
12438                 if (( $frag_lun != $last_lun )); then
12439                         if (( tot_len != 1024 )); then
12440                                 cleanup_130
12441                                 error "FIEMAP on $fm_file failed; returned " \
12442                                 "len $tot_len for OST $last_lun instead of 1024"
12443                                 return
12444                         else
12445                                 (( num_luns += 1 ))
12446                                 tot_len=0
12447                         fi
12448                 fi
12449                 (( tot_len += ext_len ))
12450                 last_lun=$frag_lun
12451         done
12452         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12453                 cleanup_130
12454                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12455                         "luns or wrong len for OST $last_lun"
12456                 return
12457         fi
12458
12459         cleanup_130
12460
12461         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12462 }
12463 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12464
12465 test_130c() {
12466         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12467
12468         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12469         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12470
12471         trap cleanup_130 EXIT RETURN
12472
12473         local fm_file=$DIR/$tfile
12474         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12475         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12476                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12477
12478         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12479                         error "dd failed on $fm_file"
12480
12481         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12482         filefrag_op=$(filefrag -ve -k $fm_file |
12483                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12484
12485         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12486                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12487
12488         IFS=$'\n'
12489         tot_len=0
12490         num_luns=1
12491         for line in $filefrag_op
12492         do
12493                 frag_lun=$(echo $line | cut -d: -f5 |
12494                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12495                 ext_len=$(echo $line | cut -d: -f4)
12496                 if (( $frag_lun != $last_lun )); then
12497                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12498                         if (( logical != 512 )); then
12499                                 cleanup_130
12500                                 error "FIEMAP on $fm_file failed; returned " \
12501                                 "logical start for lun $logical instead of 512"
12502                                 return
12503                         fi
12504                         if (( tot_len != 512 )); then
12505                                 cleanup_130
12506                                 error "FIEMAP on $fm_file failed; returned " \
12507                                 "len $tot_len for OST $last_lun instead of 1024"
12508                                 return
12509                         else
12510                                 (( num_luns += 1 ))
12511                                 tot_len=0
12512                         fi
12513                 fi
12514                 (( tot_len += ext_len ))
12515                 last_lun=$frag_lun
12516         done
12517         if (( num_luns != 2 || tot_len != 512 )); then
12518                 cleanup_130
12519                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12520                         "luns or wrong len for OST $last_lun"
12521                 return
12522         fi
12523
12524         cleanup_130
12525
12526         echo "FIEMAP on 2-stripe file with hole succeeded"
12527 }
12528 run_test 130c "FIEMAP (2-stripe file with hole)"
12529
12530 test_130d() {
12531         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12532
12533         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12534         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12535
12536         trap cleanup_130 EXIT RETURN
12537
12538         local fm_file=$DIR/$tfile
12539         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12540                         error "setstripe on $fm_file"
12541         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12542                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12543
12544         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12545         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12546                 error "dd failed on $fm_file"
12547
12548         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12549         filefrag_op=$(filefrag -ve -k $fm_file |
12550                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12551
12552         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12553                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12554
12555         IFS=$'\n'
12556         tot_len=0
12557         num_luns=1
12558         for line in $filefrag_op
12559         do
12560                 frag_lun=$(echo $line | cut -d: -f5 |
12561                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12562                 ext_len=$(echo $line | cut -d: -f4)
12563                 if (( $frag_lun != $last_lun )); then
12564                         if (( tot_len != 1024 )); then
12565                                 cleanup_130
12566                                 error "FIEMAP on $fm_file failed; returned " \
12567                                 "len $tot_len for OST $last_lun instead of 1024"
12568                                 return
12569                         else
12570                                 (( num_luns += 1 ))
12571                                 tot_len=0
12572                         fi
12573                 fi
12574                 (( tot_len += ext_len ))
12575                 last_lun=$frag_lun
12576         done
12577         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12578                 cleanup_130
12579                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12580                         "luns or wrong len for OST $last_lun"
12581                 return
12582         fi
12583
12584         cleanup_130
12585
12586         echo "FIEMAP on N-stripe file succeeded"
12587 }
12588 run_test 130d "FIEMAP (N-stripe file)"
12589
12590 test_130e() {
12591         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12592
12593         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12594         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12595
12596         trap cleanup_130 EXIT RETURN
12597
12598         local fm_file=$DIR/$tfile
12599         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12600         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12601                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12602
12603         NUM_BLKS=512
12604         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12605         for ((i = 0; i < $NUM_BLKS; i++))
12606         do
12607                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12608         done
12609
12610         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12611         filefrag_op=$(filefrag -ve -k $fm_file |
12612                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12613
12614         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12615                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12616
12617         IFS=$'\n'
12618         tot_len=0
12619         num_luns=1
12620         for line in $filefrag_op
12621         do
12622                 frag_lun=$(echo $line | cut -d: -f5 |
12623                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12624                 ext_len=$(echo $line | cut -d: -f4)
12625                 if (( $frag_lun != $last_lun )); then
12626                         if (( tot_len != $EXPECTED_LEN )); then
12627                                 cleanup_130
12628                                 error "FIEMAP on $fm_file failed; returned " \
12629                                 "len $tot_len for OST $last_lun instead " \
12630                                 "of $EXPECTED_LEN"
12631                                 return
12632                         else
12633                                 (( num_luns += 1 ))
12634                                 tot_len=0
12635                         fi
12636                 fi
12637                 (( tot_len += ext_len ))
12638                 last_lun=$frag_lun
12639         done
12640         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12641                 cleanup_130
12642                 error "FIEMAP on $fm_file failed; returned wrong number " \
12643                         "of luns or wrong len for OST $last_lun"
12644                 return
12645         fi
12646
12647         cleanup_130
12648
12649         echo "FIEMAP with continuation calls succeeded"
12650 }
12651 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12652
12653 test_130f() {
12654         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12655         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12656
12657         local fm_file=$DIR/$tfile
12658         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12659                 error "multiop create with lov_delay_create on $fm_file"
12660
12661         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12662         filefrag_extents=$(filefrag -vek $fm_file |
12663                            awk '/extents? found/ { print $2 }')
12664         if [[ "$filefrag_extents" != "0" ]]; then
12665                 error "FIEMAP on $fm_file failed; " \
12666                       "returned $filefrag_extents expected 0"
12667         fi
12668
12669         rm -f $fm_file
12670 }
12671 run_test 130f "FIEMAP (unstriped file)"
12672
12673 # Test for writev/readv
12674 test_131a() {
12675         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12676                 error "writev test failed"
12677         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12678                 error "readv failed"
12679         rm -f $DIR/$tfile
12680 }
12681 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12682
12683 test_131b() {
12684         local fsize=$((524288 + 1048576 + 1572864))
12685         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12686                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12687                         error "append writev test failed"
12688
12689         ((fsize += 1572864 + 1048576))
12690         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12691                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12692                         error "append writev test failed"
12693         rm -f $DIR/$tfile
12694 }
12695 run_test 131b "test append writev"
12696
12697 test_131c() {
12698         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12699         error "NOT PASS"
12700 }
12701 run_test 131c "test read/write on file w/o objects"
12702
12703 test_131d() {
12704         rwv -f $DIR/$tfile -w -n 1 1572864
12705         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12706         if [ "$NOB" != 1572864 ]; then
12707                 error "Short read filed: read $NOB bytes instead of 1572864"
12708         fi
12709         rm -f $DIR/$tfile
12710 }
12711 run_test 131d "test short read"
12712
12713 test_131e() {
12714         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12715         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12716         error "read hitting hole failed"
12717         rm -f $DIR/$tfile
12718 }
12719 run_test 131e "test read hitting hole"
12720
12721 check_stats() {
12722         local facet=$1
12723         local op=$2
12724         local want=${3:-0}
12725         local res
12726
12727         case $facet in
12728         mds*) res=$(do_facet $facet \
12729                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12730                  ;;
12731         ost*) res=$(do_facet $facet \
12732                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12733                  ;;
12734         *) error "Wrong facet '$facet'" ;;
12735         esac
12736         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12737         # if the argument $3 is zero, it means any stat increment is ok.
12738         if [[ $want -gt 0 ]]; then
12739                 local count=$(echo $res | awk '{ print $2 }')
12740                 [[ $count -ne $want ]] &&
12741                         error "The $op counter on $facet is $count, not $want"
12742         fi
12743 }
12744
12745 test_133a() {
12746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12747         remote_ost_nodsh && skip "remote OST with nodsh"
12748         remote_mds_nodsh && skip "remote MDS with nodsh"
12749         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12750                 skip_env "MDS doesn't support rename stats"
12751
12752         local testdir=$DIR/${tdir}/stats_testdir
12753
12754         mkdir -p $DIR/${tdir}
12755
12756         # clear stats.
12757         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12758         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12759
12760         # verify mdt stats first.
12761         mkdir ${testdir} || error "mkdir failed"
12762         check_stats $SINGLEMDS "mkdir" 1
12763         touch ${testdir}/${tfile} || error "touch failed"
12764         check_stats $SINGLEMDS "open" 1
12765         check_stats $SINGLEMDS "close" 1
12766         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12767                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12768                 check_stats $SINGLEMDS "mknod" 2
12769         }
12770         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12771         check_stats $SINGLEMDS "unlink" 1
12772         rm -f ${testdir}/${tfile} || error "file remove failed"
12773         check_stats $SINGLEMDS "unlink" 2
12774
12775         # remove working dir and check mdt stats again.
12776         rmdir ${testdir} || error "rmdir failed"
12777         check_stats $SINGLEMDS "rmdir" 1
12778
12779         local testdir1=$DIR/${tdir}/stats_testdir1
12780         mkdir -p ${testdir}
12781         mkdir -p ${testdir1}
12782         touch ${testdir1}/test1
12783         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12784         check_stats $SINGLEMDS "crossdir_rename" 1
12785
12786         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12787         check_stats $SINGLEMDS "samedir_rename" 1
12788
12789         rm -rf $DIR/${tdir}
12790 }
12791 run_test 133a "Verifying MDT stats ========================================"
12792
12793 test_133b() {
12794         local res
12795
12796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12797         remote_ost_nodsh && skip "remote OST with nodsh"
12798         remote_mds_nodsh && skip "remote MDS with nodsh"
12799
12800         local testdir=$DIR/${tdir}/stats_testdir
12801
12802         mkdir -p ${testdir} || error "mkdir failed"
12803         touch ${testdir}/${tfile} || error "touch failed"
12804         cancel_lru_locks mdc
12805
12806         # clear stats.
12807         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12808         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12809
12810         # extra mdt stats verification.
12811         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12812         check_stats $SINGLEMDS "setattr" 1
12813         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12814         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12815         then            # LU-1740
12816                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12817                 check_stats $SINGLEMDS "getattr" 1
12818         fi
12819         rm -rf $DIR/${tdir}
12820
12821         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12822         # so the check below is not reliable
12823         [ $MDSCOUNT -eq 1 ] || return 0
12824
12825         # Sleep to avoid a cached response.
12826         #define OBD_STATFS_CACHE_SECONDS 1
12827         sleep 2
12828         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12829         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12830         $LFS df || error "lfs failed"
12831         check_stats $SINGLEMDS "statfs" 1
12832
12833         # check aggregated statfs (LU-10018)
12834         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12835                 return 0
12836         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12837                 return 0
12838         sleep 2
12839         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12840         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12841         df $DIR
12842         check_stats $SINGLEMDS "statfs" 1
12843
12844         # We want to check that the client didn't send OST_STATFS to
12845         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12846         # extra care is needed here.
12847         if remote_mds; then
12848                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12849                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12850
12851                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12852                 [ "$res" ] && error "OST got STATFS"
12853         fi
12854
12855         return 0
12856 }
12857 run_test 133b "Verifying extra MDT stats =================================="
12858
12859 test_133c() {
12860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12861         remote_ost_nodsh && skip "remote OST with nodsh"
12862         remote_mds_nodsh && skip "remote MDS with nodsh"
12863
12864         local testdir=$DIR/$tdir/stats_testdir
12865
12866         test_mkdir -p $testdir
12867
12868         # verify obdfilter stats.
12869         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12870         sync
12871         cancel_lru_locks osc
12872         wait_delete_completed
12873
12874         # clear stats.
12875         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12876         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12877
12878         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12879                 error "dd failed"
12880         sync
12881         cancel_lru_locks osc
12882         check_stats ost1 "write" 1
12883
12884         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12885         check_stats ost1 "read" 1
12886
12887         > $testdir/$tfile || error "truncate failed"
12888         check_stats ost1 "punch" 1
12889
12890         rm -f $testdir/$tfile || error "file remove failed"
12891         wait_delete_completed
12892         check_stats ost1 "destroy" 1
12893
12894         rm -rf $DIR/$tdir
12895 }
12896 run_test 133c "Verifying OST stats ========================================"
12897
12898 order_2() {
12899         local value=$1
12900         local orig=$value
12901         local order=1
12902
12903         while [ $value -ge 2 ]; do
12904                 order=$((order*2))
12905                 value=$((value/2))
12906         done
12907
12908         if [ $orig -gt $order ]; then
12909                 order=$((order*2))
12910         fi
12911         echo $order
12912 }
12913
12914 size_in_KMGT() {
12915     local value=$1
12916     local size=('K' 'M' 'G' 'T');
12917     local i=0
12918     local size_string=$value
12919
12920     while [ $value -ge 1024 ]; do
12921         if [ $i -gt 3 ]; then
12922             #T is the biggest unit we get here, if that is bigger,
12923             #just return XXXT
12924             size_string=${value}T
12925             break
12926         fi
12927         value=$((value >> 10))
12928         if [ $value -lt 1024 ]; then
12929             size_string=${value}${size[$i]}
12930             break
12931         fi
12932         i=$((i + 1))
12933     done
12934
12935     echo $size_string
12936 }
12937
12938 get_rename_size() {
12939         local size=$1
12940         local context=${2:-.}
12941         local sample=$(do_facet $SINGLEMDS $LCTL \
12942                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12943                 grep -A1 $context |
12944                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12945         echo $sample
12946 }
12947
12948 test_133d() {
12949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12950         remote_ost_nodsh && skip "remote OST with nodsh"
12951         remote_mds_nodsh && skip "remote MDS with nodsh"
12952         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12953                 skip_env "MDS doesn't support rename stats"
12954
12955         local testdir1=$DIR/${tdir}/stats_testdir1
12956         local testdir2=$DIR/${tdir}/stats_testdir2
12957         mkdir -p $DIR/${tdir}
12958
12959         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12960
12961         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12962         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12963
12964         createmany -o $testdir1/test 512 || error "createmany failed"
12965
12966         # check samedir rename size
12967         mv ${testdir1}/test0 ${testdir1}/test_0
12968
12969         local testdir1_size=$(ls -l $DIR/${tdir} |
12970                 awk '/stats_testdir1/ {print $5}')
12971         local testdir2_size=$(ls -l $DIR/${tdir} |
12972                 awk '/stats_testdir2/ {print $5}')
12973
12974         testdir1_size=$(order_2 $testdir1_size)
12975         testdir2_size=$(order_2 $testdir2_size)
12976
12977         testdir1_size=$(size_in_KMGT $testdir1_size)
12978         testdir2_size=$(size_in_KMGT $testdir2_size)
12979
12980         echo "source rename dir size: ${testdir1_size}"
12981         echo "target rename dir size: ${testdir2_size}"
12982
12983         local cmd="do_facet $SINGLEMDS $LCTL "
12984         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12985
12986         eval $cmd || error "$cmd failed"
12987         local samedir=$($cmd | grep 'same_dir')
12988         local same_sample=$(get_rename_size $testdir1_size)
12989         [ -z "$samedir" ] && error "samedir_rename_size count error"
12990         [[ $same_sample -eq 1 ]] ||
12991                 error "samedir_rename_size error $same_sample"
12992         echo "Check same dir rename stats success"
12993
12994         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12995
12996         # check crossdir rename size
12997         mv ${testdir1}/test_0 ${testdir2}/test_0
12998
12999         testdir1_size=$(ls -l $DIR/${tdir} |
13000                 awk '/stats_testdir1/ {print $5}')
13001         testdir2_size=$(ls -l $DIR/${tdir} |
13002                 awk '/stats_testdir2/ {print $5}')
13003
13004         testdir1_size=$(order_2 $testdir1_size)
13005         testdir2_size=$(order_2 $testdir2_size)
13006
13007         testdir1_size=$(size_in_KMGT $testdir1_size)
13008         testdir2_size=$(size_in_KMGT $testdir2_size)
13009
13010         echo "source rename dir size: ${testdir1_size}"
13011         echo "target rename dir size: ${testdir2_size}"
13012
13013         eval $cmd || error "$cmd failed"
13014         local crossdir=$($cmd | grep 'crossdir')
13015         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13016         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13017         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13018         [[ $src_sample -eq 1 ]] ||
13019                 error "crossdir_rename_size error $src_sample"
13020         [[ $tgt_sample -eq 1 ]] ||
13021                 error "crossdir_rename_size error $tgt_sample"
13022         echo "Check cross dir rename stats success"
13023         rm -rf $DIR/${tdir}
13024 }
13025 run_test 133d "Verifying rename_stats ========================================"
13026
13027 test_133e() {
13028         remote_mds_nodsh && skip "remote MDS with nodsh"
13029         remote_ost_nodsh && skip "remote OST with nodsh"
13030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13031
13032         local testdir=$DIR/${tdir}/stats_testdir
13033         local ctr f0 f1 bs=32768 count=42 sum
13034
13035         mkdir -p ${testdir} || error "mkdir failed"
13036
13037         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13038
13039         for ctr in {write,read}_bytes; do
13040                 sync
13041                 cancel_lru_locks osc
13042
13043                 do_facet ost1 $LCTL set_param -n \
13044                         "obdfilter.*.exports.clear=clear"
13045
13046                 if [ $ctr = write_bytes ]; then
13047                         f0=/dev/zero
13048                         f1=${testdir}/${tfile}
13049                 else
13050                         f0=${testdir}/${tfile}
13051                         f1=/dev/null
13052                 fi
13053
13054                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13055                         error "dd failed"
13056                 sync
13057                 cancel_lru_locks osc
13058
13059                 sum=$(do_facet ost1 $LCTL get_param \
13060                         "obdfilter.*.exports.*.stats" |
13061                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13062                                 $1 == ctr { sum += $7 }
13063                                 END { printf("%0.0f", sum) }')
13064
13065                 if ((sum != bs * count)); then
13066                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13067                 fi
13068         done
13069
13070         rm -rf $DIR/${tdir}
13071 }
13072 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13073
13074 test_133f() {
13075         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13076                 skip "too old lustre for get_param -R ($facet_ver)"
13077
13078         # verifying readability.
13079         $LCTL get_param -R '*' &> /dev/null
13080
13081         # Verifing writability with badarea_io.
13082         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13083                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13084                 error "client badarea_io failed"
13085
13086         # remount the FS in case writes/reads /proc break the FS
13087         cleanup || error "failed to unmount"
13088         setup || error "failed to setup"
13089 }
13090 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13091
13092 test_133g() {
13093         remote_mds_nodsh && skip "remote MDS with nodsh"
13094         remote_ost_nodsh && skip "remote OST with nodsh"
13095
13096         local facet
13097         for facet in mds1 ost1; do
13098                 local facet_ver=$(lustre_version_code $facet)
13099                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13100                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13101                 else
13102                         log "$facet: too old lustre for get_param -R"
13103                 fi
13104                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13105                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13106                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13107                                 xargs badarea_io" ||
13108                                         error "$facet badarea_io failed"
13109                 else
13110                         skip_noexit "$facet: too old lustre for get_param -R"
13111                 fi
13112         done
13113
13114         # remount the FS in case writes/reads /proc break the FS
13115         cleanup || error "failed to unmount"
13116         setup || error "failed to setup"
13117 }
13118 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13119
13120 test_133h() {
13121         remote_mds_nodsh && skip "remote MDS with nodsh"
13122         remote_ost_nodsh && skip "remote OST with nodsh"
13123         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13124                 skip "Need MDS version at least 2.9.54"
13125
13126         local facet
13127         for facet in client mds1 ost1; do
13128                 # Get the list of files that are missing the terminating newline
13129                 local plist=$(do_facet $facet
13130                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13131                 local ent
13132                 for ent in $plist; do
13133                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13134                                 awk -v FS='\v' -v RS='\v\v' \
13135                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13136                                         print FILENAME}'" 2>/dev/null)
13137                         [ -z $missing ] || {
13138                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13139                                 error "file does not end with newline: $facet-$ent"
13140                         }
13141                 done
13142         done
13143 }
13144 run_test 133h "Proc files should end with newlines"
13145
13146 test_134a() {
13147         remote_mds_nodsh && skip "remote MDS with nodsh"
13148         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13149                 skip "Need MDS version at least 2.7.54"
13150
13151         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13152         cancel_lru_locks mdc
13153
13154         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13155         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13156         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13157
13158         local nr=1000
13159         createmany -o $DIR/$tdir/f $nr ||
13160                 error "failed to create $nr files in $DIR/$tdir"
13161         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13162
13163         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13164         do_facet mds1 $LCTL set_param fail_loc=0x327
13165         do_facet mds1 $LCTL set_param fail_val=500
13166         touch $DIR/$tdir/m
13167
13168         echo "sleep 10 seconds ..."
13169         sleep 10
13170         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13171
13172         do_facet mds1 $LCTL set_param fail_loc=0
13173         do_facet mds1 $LCTL set_param fail_val=0
13174         [ $lck_cnt -lt $unused ] ||
13175                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13176
13177         rm $DIR/$tdir/m
13178         unlinkmany $DIR/$tdir/f $nr
13179 }
13180 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13181
13182 test_134b() {
13183         remote_mds_nodsh && skip "remote MDS with nodsh"
13184         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13185                 skip "Need MDS version at least 2.7.54"
13186
13187         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13188         cancel_lru_locks mdc
13189
13190         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13191                         ldlm.lock_reclaim_threshold_mb)
13192         # disable reclaim temporarily
13193         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13194
13195         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13196         do_facet mds1 $LCTL set_param fail_loc=0x328
13197         do_facet mds1 $LCTL set_param fail_val=500
13198
13199         $LCTL set_param debug=+trace
13200
13201         local nr=600
13202         createmany -o $DIR/$tdir/f $nr &
13203         local create_pid=$!
13204
13205         echo "Sleep $TIMEOUT seconds ..."
13206         sleep $TIMEOUT
13207         if ! ps -p $create_pid  > /dev/null 2>&1; then
13208                 do_facet mds1 $LCTL set_param fail_loc=0
13209                 do_facet mds1 $LCTL set_param fail_val=0
13210                 do_facet mds1 $LCTL set_param \
13211                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13212                 error "createmany finished incorrectly!"
13213         fi
13214         do_facet mds1 $LCTL set_param fail_loc=0
13215         do_facet mds1 $LCTL set_param fail_val=0
13216         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13217         wait $create_pid || return 1
13218
13219         unlinkmany $DIR/$tdir/f $nr
13220 }
13221 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13222
13223 test_135() {
13224         remote_mds_nodsh && skip "remote MDS with nodsh"
13225         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13226                 skip "Need MDS version at least 2.13.50"
13227         local fname
13228
13229         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13230
13231 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13232         #set only one record at plain llog
13233         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13234
13235         #fill already existed plain llog each 64767
13236         #wrapping whole catalog
13237         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13238
13239         createmany -o $DIR/$tdir/$tfile_ 64700
13240         for (( i = 0; i < 64700; i = i + 2 ))
13241         do
13242                 rm $DIR/$tdir/$tfile_$i &
13243                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13244                 local pid=$!
13245                 wait $pid
13246         done
13247
13248         #waiting osp synchronization
13249         wait_delete_completed
13250 }
13251 run_test 135 "Race catalog processing"
13252
13253 test_136() {
13254         remote_mds_nodsh && skip "remote MDS with nodsh"
13255         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13256                 skip "Need MDS version at least 2.13.50"
13257         local fname
13258
13259         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13260         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13261         #set only one record at plain llog
13262 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13263         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13264
13265         #fill already existed 2 plain llogs each 64767
13266         #wrapping whole catalog
13267         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13268         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13269         wait_delete_completed
13270
13271         createmany -o $DIR/$tdir/$tfile_ 10
13272         sleep 25
13273
13274         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13275         for (( i = 0; i < 10; i = i + 3 ))
13276         do
13277                 rm $DIR/$tdir/$tfile_$i &
13278                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13279                 local pid=$!
13280                 wait $pid
13281                 sleep 7
13282                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13283         done
13284
13285         #waiting osp synchronization
13286         wait_delete_completed
13287 }
13288 run_test 136 "Race catalog processing 2"
13289
13290 test_140() { #bug-17379
13291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13292
13293         test_mkdir $DIR/$tdir
13294         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13295         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13296
13297         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13298         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13299         local i=0
13300         while i=$((i + 1)); do
13301                 test_mkdir $i
13302                 cd $i || error "Changing to $i"
13303                 ln -s ../stat stat || error "Creating stat symlink"
13304                 # Read the symlink until ELOOP present,
13305                 # not LBUGing the system is considered success,
13306                 # we didn't overrun the stack.
13307                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13308                 if [ $ret -ne 0 ]; then
13309                         if [ $ret -eq 40 ]; then
13310                                 break  # -ELOOP
13311                         else
13312                                 error "Open stat symlink"
13313                                         return
13314                         fi
13315                 fi
13316         done
13317         i=$((i - 1))
13318         echo "The symlink depth = $i"
13319         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13320                 error "Invalid symlink depth"
13321
13322         # Test recursive symlink
13323         ln -s symlink_self symlink_self
13324         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13325         echo "open symlink_self returns $ret"
13326         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13327 }
13328 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13329
13330 test_150a() {
13331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13332
13333         local TF="$TMP/$tfile"
13334
13335         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13336         cp $TF $DIR/$tfile
13337         cancel_lru_locks $OSC
13338         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13339         remount_client $MOUNT
13340         df -P $MOUNT
13341         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13342
13343         $TRUNCATE $TF 6000
13344         $TRUNCATE $DIR/$tfile 6000
13345         cancel_lru_locks $OSC
13346         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13347
13348         echo "12345" >>$TF
13349         echo "12345" >>$DIR/$tfile
13350         cancel_lru_locks $OSC
13351         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13352
13353         echo "12345" >>$TF
13354         echo "12345" >>$DIR/$tfile
13355         cancel_lru_locks $OSC
13356         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13357
13358         rm -f $TF
13359         true
13360 }
13361 run_test 150a "truncate/append tests"
13362
13363 test_150b() {
13364         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13365         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13366                 skip "Need OST version at least 2.13.53"
13367         touch $DIR/$tfile
13368         check_fallocate $DIR/$tfile || error "fallocate failed"
13369 }
13370 run_test 150b "Verify fallocate (prealloc) functionality"
13371
13372 test_150c() {
13373         local bytes
13374         local want
13375
13376         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13377         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13378                 skip "Need OST version at least 2.13.53"
13379
13380         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13381         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13382         sync; sync_all_data
13383         cancel_lru_locks $OSC
13384         sleep 5
13385         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13386         want=$((OSTCOUNT * 1048576))
13387
13388         # Must allocate all requested space, not more than 5% extra
13389         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13390                 error "bytes $bytes is not $want"
13391 }
13392 run_test 150c "Verify fallocate Size and Blocks"
13393
13394 test_150d() {
13395         local bytes
13396         local want
13397
13398         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13399         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13400                 skip "Need OST version at least 2.13.53"
13401
13402         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13403         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13404         sync; sync_all_data
13405         cancel_lru_locks $OSC
13406         sleep 5
13407         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13408         want=$((OSTCOUNT * 1048576))
13409
13410         # Must allocate all requested space, not more than 5% extra
13411         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13412                 error "bytes $bytes is not $want"
13413 }
13414 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13415
13416 #LU-2902 roc_hit was not able to read all values from lproc
13417 function roc_hit_init() {
13418         local list=$(comma_list $(osts_nodes))
13419         local dir=$DIR/$tdir-check
13420         local file=$dir/$tfile
13421         local BEFORE
13422         local AFTER
13423         local idx
13424
13425         test_mkdir $dir
13426         #use setstripe to do a write to every ost
13427         for i in $(seq 0 $((OSTCOUNT-1))); do
13428                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13429                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13430                 idx=$(printf %04x $i)
13431                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13432                         awk '$1 == "cache_access" {sum += $7}
13433                                 END { printf("%0.0f", sum) }')
13434
13435                 cancel_lru_locks osc
13436                 cat $file >/dev/null
13437
13438                 AFTER=$(get_osd_param $list *OST*$idx stats |
13439                         awk '$1 == "cache_access" {sum += $7}
13440                                 END { printf("%0.0f", sum) }')
13441
13442                 echo BEFORE:$BEFORE AFTER:$AFTER
13443                 if ! let "AFTER - BEFORE == 4"; then
13444                         rm -rf $dir
13445                         error "roc_hit is not safe to use"
13446                 fi
13447                 rm $file
13448         done
13449
13450         rm -rf $dir
13451 }
13452
13453 function roc_hit() {
13454         local list=$(comma_list $(osts_nodes))
13455         echo $(get_osd_param $list '' stats |
13456                 awk '$1 == "cache_hit" {sum += $7}
13457                         END { printf("%0.0f", sum) }')
13458 }
13459
13460 function set_cache() {
13461         local on=1
13462
13463         if [ "$2" == "off" ]; then
13464                 on=0;
13465         fi
13466         local list=$(comma_list $(osts_nodes))
13467         set_osd_param $list '' $1_cache_enable $on
13468
13469         cancel_lru_locks osc
13470 }
13471
13472 test_151() {
13473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13474         remote_ost_nodsh && skip "remote OST with nodsh"
13475
13476         local CPAGES=3
13477         local list=$(comma_list $(osts_nodes))
13478
13479         # check whether obdfilter is cache capable at all
13480         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13481                 skip "not cache-capable obdfilter"
13482         fi
13483
13484         # check cache is enabled on all obdfilters
13485         if get_osd_param $list '' read_cache_enable | grep 0; then
13486                 skip "oss cache is disabled"
13487         fi
13488
13489         set_osd_param $list '' writethrough_cache_enable 1
13490
13491         # check write cache is enabled on all obdfilters
13492         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13493                 skip "oss write cache is NOT enabled"
13494         fi
13495
13496         roc_hit_init
13497
13498         #define OBD_FAIL_OBD_NO_LRU  0x609
13499         do_nodes $list $LCTL set_param fail_loc=0x609
13500
13501         # pages should be in the case right after write
13502         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13503                 error "dd failed"
13504
13505         local BEFORE=$(roc_hit)
13506         cancel_lru_locks osc
13507         cat $DIR/$tfile >/dev/null
13508         local AFTER=$(roc_hit)
13509
13510         do_nodes $list $LCTL set_param fail_loc=0
13511
13512         if ! let "AFTER - BEFORE == CPAGES"; then
13513                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13514         fi
13515
13516         cancel_lru_locks osc
13517         # invalidates OST cache
13518         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13519         set_osd_param $list '' read_cache_enable 0
13520         cat $DIR/$tfile >/dev/null
13521
13522         # now data shouldn't be found in the cache
13523         BEFORE=$(roc_hit)
13524         cancel_lru_locks osc
13525         cat $DIR/$tfile >/dev/null
13526         AFTER=$(roc_hit)
13527         if let "AFTER - BEFORE != 0"; then
13528                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13529         fi
13530
13531         set_osd_param $list '' read_cache_enable 1
13532         rm -f $DIR/$tfile
13533 }
13534 run_test 151 "test cache on oss and controls ==============================="
13535
13536 test_152() {
13537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13538
13539         local TF="$TMP/$tfile"
13540
13541         # simulate ENOMEM during write
13542 #define OBD_FAIL_OST_NOMEM      0x226
13543         lctl set_param fail_loc=0x80000226
13544         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13545         cp $TF $DIR/$tfile
13546         sync || error "sync failed"
13547         lctl set_param fail_loc=0
13548
13549         # discard client's cache
13550         cancel_lru_locks osc
13551
13552         # simulate ENOMEM during read
13553         lctl set_param fail_loc=0x80000226
13554         cmp $TF $DIR/$tfile || error "cmp failed"
13555         lctl set_param fail_loc=0
13556
13557         rm -f $TF
13558 }
13559 run_test 152 "test read/write with enomem ============================"
13560
13561 test_153() {
13562         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13563 }
13564 run_test 153 "test if fdatasync does not crash ======================="
13565
13566 dot_lustre_fid_permission_check() {
13567         local fid=$1
13568         local ffid=$MOUNT/.lustre/fid/$fid
13569         local test_dir=$2
13570
13571         echo "stat fid $fid"
13572         stat $ffid > /dev/null || error "stat $ffid failed."
13573         echo "touch fid $fid"
13574         touch $ffid || error "touch $ffid failed."
13575         echo "write to fid $fid"
13576         cat /etc/hosts > $ffid || error "write $ffid failed."
13577         echo "read fid $fid"
13578         diff /etc/hosts $ffid || error "read $ffid failed."
13579         echo "append write to fid $fid"
13580         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13581         echo "rename fid $fid"
13582         mv $ffid $test_dir/$tfile.1 &&
13583                 error "rename $ffid to $tfile.1 should fail."
13584         touch $test_dir/$tfile.1
13585         mv $test_dir/$tfile.1 $ffid &&
13586                 error "rename $tfile.1 to $ffid should fail."
13587         rm -f $test_dir/$tfile.1
13588         echo "truncate fid $fid"
13589         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13590         echo "link fid $fid"
13591         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13592         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13593                 echo "setfacl fid $fid"
13594                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13595                 echo "getfacl fid $fid"
13596                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13597         fi
13598         echo "unlink fid $fid"
13599         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13600         echo "mknod fid $fid"
13601         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13602
13603         fid=[0xf00000400:0x1:0x0]
13604         ffid=$MOUNT/.lustre/fid/$fid
13605
13606         echo "stat non-exist fid $fid"
13607         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13608         echo "write to non-exist fid $fid"
13609         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13610         echo "link new fid $fid"
13611         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13612
13613         mkdir -p $test_dir/$tdir
13614         touch $test_dir/$tdir/$tfile
13615         fid=$($LFS path2fid $test_dir/$tdir)
13616         rc=$?
13617         [ $rc -ne 0 ] &&
13618                 error "error: could not get fid for $test_dir/$dir/$tfile."
13619
13620         ffid=$MOUNT/.lustre/fid/$fid
13621
13622         echo "ls $fid"
13623         ls $ffid > /dev/null || error "ls $ffid failed."
13624         echo "touch $fid/$tfile.1"
13625         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13626
13627         echo "touch $MOUNT/.lustre/fid/$tfile"
13628         touch $MOUNT/.lustre/fid/$tfile && \
13629                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13630
13631         echo "setxattr to $MOUNT/.lustre/fid"
13632         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13633
13634         echo "listxattr for $MOUNT/.lustre/fid"
13635         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13636
13637         echo "delxattr from $MOUNT/.lustre/fid"
13638         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13639
13640         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13641         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13642                 error "touch invalid fid should fail."
13643
13644         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13645         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13646                 error "touch non-normal fid should fail."
13647
13648         echo "rename $tdir to $MOUNT/.lustre/fid"
13649         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13650                 error "rename to $MOUNT/.lustre/fid should fail."
13651
13652         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13653         then            # LU-3547
13654                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13655                 local new_obf_mode=777
13656
13657                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13658                 chmod $new_obf_mode $DIR/.lustre/fid ||
13659                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13660
13661                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13662                 [ $obf_mode -eq $new_obf_mode ] ||
13663                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13664
13665                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13666                 chmod $old_obf_mode $DIR/.lustre/fid ||
13667                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13668         fi
13669
13670         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13671         fid=$($LFS path2fid $test_dir/$tfile-2)
13672
13673         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13674         then # LU-5424
13675                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13676                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13677                         error "create lov data thru .lustre failed"
13678         fi
13679         echo "cp /etc/passwd $test_dir/$tfile-2"
13680         cp /etc/passwd $test_dir/$tfile-2 ||
13681                 error "copy to $test_dir/$tfile-2 failed."
13682         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13683         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13684                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13685
13686         rm -rf $test_dir/tfile.lnk
13687         rm -rf $test_dir/$tfile-2
13688 }
13689
13690 test_154A() {
13691         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13692                 skip "Need MDS version at least 2.4.1"
13693
13694         local tf=$DIR/$tfile
13695         touch $tf
13696
13697         local fid=$($LFS path2fid $tf)
13698         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13699
13700         # check that we get the same pathname back
13701         local rootpath
13702         local found
13703         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13704                 echo "$rootpath $fid"
13705                 found=$($LFS fid2path $rootpath "$fid")
13706                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13707                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13708         done
13709
13710         # check wrong root path format
13711         rootpath=$MOUNT"_wrong"
13712         found=$($LFS fid2path $rootpath "$fid")
13713         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13714 }
13715 run_test 154A "lfs path2fid and fid2path basic checks"
13716
13717 test_154B() {
13718         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13719                 skip "Need MDS version at least 2.4.1"
13720
13721         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13722         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13723         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13724         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13725
13726         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13727         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13728
13729         # check that we get the same pathname
13730         echo "PFID: $PFID, name: $name"
13731         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13732         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13733         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13734                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13735
13736         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13737 }
13738 run_test 154B "verify the ll_decode_linkea tool"
13739
13740 test_154a() {
13741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13742         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13743         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13744                 skip "Need MDS version at least 2.2.51"
13745         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13746
13747         cp /etc/hosts $DIR/$tfile
13748
13749         fid=$($LFS path2fid $DIR/$tfile)
13750         rc=$?
13751         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13752
13753         dot_lustre_fid_permission_check "$fid" $DIR ||
13754                 error "dot lustre permission check $fid failed"
13755
13756         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13757
13758         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13759
13760         touch $MOUNT/.lustre/file &&
13761                 error "creation is not allowed under .lustre"
13762
13763         mkdir $MOUNT/.lustre/dir &&
13764                 error "mkdir is not allowed under .lustre"
13765
13766         rm -rf $DIR/$tfile
13767 }
13768 run_test 154a "Open-by-FID"
13769
13770 test_154b() {
13771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13772         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13773         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13774         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13775                 skip "Need MDS version at least 2.2.51"
13776
13777         local remote_dir=$DIR/$tdir/remote_dir
13778         local MDTIDX=1
13779         local rc=0
13780
13781         mkdir -p $DIR/$tdir
13782         $LFS mkdir -i $MDTIDX $remote_dir ||
13783                 error "create remote directory failed"
13784
13785         cp /etc/hosts $remote_dir/$tfile
13786
13787         fid=$($LFS path2fid $remote_dir/$tfile)
13788         rc=$?
13789         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13790
13791         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13792                 error "dot lustre permission check $fid failed"
13793         rm -rf $DIR/$tdir
13794 }
13795 run_test 154b "Open-by-FID for remote directory"
13796
13797 test_154c() {
13798         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13799                 skip "Need MDS version at least 2.4.1"
13800
13801         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13802         local FID1=$($LFS path2fid $DIR/$tfile.1)
13803         local FID2=$($LFS path2fid $DIR/$tfile.2)
13804         local FID3=$($LFS path2fid $DIR/$tfile.3)
13805
13806         local N=1
13807         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13808                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13809                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13810                 local want=FID$N
13811                 [ "$FID" = "${!want}" ] ||
13812                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13813                 N=$((N + 1))
13814         done
13815
13816         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13817         do
13818                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13819                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13820                 N=$((N + 1))
13821         done
13822 }
13823 run_test 154c "lfs path2fid and fid2path multiple arguments"
13824
13825 test_154d() {
13826         remote_mds_nodsh && skip "remote MDS with nodsh"
13827         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13828                 skip "Need MDS version at least 2.5.53"
13829
13830         if remote_mds; then
13831                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13832         else
13833                 nid="0@lo"
13834         fi
13835         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13836         local fd
13837         local cmd
13838
13839         rm -f $DIR/$tfile
13840         touch $DIR/$tfile
13841
13842         local fid=$($LFS path2fid $DIR/$tfile)
13843         # Open the file
13844         fd=$(free_fd)
13845         cmd="exec $fd<$DIR/$tfile"
13846         eval $cmd
13847         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13848         echo "$fid_list" | grep "$fid"
13849         rc=$?
13850
13851         cmd="exec $fd>/dev/null"
13852         eval $cmd
13853         if [ $rc -ne 0 ]; then
13854                 error "FID $fid not found in open files list $fid_list"
13855         fi
13856 }
13857 run_test 154d "Verify open file fid"
13858
13859 test_154e()
13860 {
13861         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13862                 skip "Need MDS version at least 2.6.50"
13863
13864         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13865                 error ".lustre returned by readdir"
13866         fi
13867 }
13868 run_test 154e ".lustre is not returned by readdir"
13869
13870 test_154f() {
13871         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13872
13873         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13874         test_mkdir -p -c1 $DIR/$tdir/d
13875         # test dirs inherit from its stripe
13876         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13877         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13878         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13879         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13880         touch $DIR/f
13881
13882         # get fid of parents
13883         local FID0=$($LFS path2fid $DIR/$tdir/d)
13884         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13885         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13886         local FID3=$($LFS path2fid $DIR)
13887
13888         # check that path2fid --parents returns expected <parent_fid>/name
13889         # 1) test for a directory (single parent)
13890         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13891         [ "$parent" == "$FID0/foo1" ] ||
13892                 error "expected parent: $FID0/foo1, got: $parent"
13893
13894         # 2) test for a file with nlink > 1 (multiple parents)
13895         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13896         echo "$parent" | grep -F "$FID1/$tfile" ||
13897                 error "$FID1/$tfile not returned in parent list"
13898         echo "$parent" | grep -F "$FID2/link" ||
13899                 error "$FID2/link not returned in parent list"
13900
13901         # 3) get parent by fid
13902         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13903         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13904         echo "$parent" | grep -F "$FID1/$tfile" ||
13905                 error "$FID1/$tfile not returned in parent list (by fid)"
13906         echo "$parent" | grep -F "$FID2/link" ||
13907                 error "$FID2/link not returned in parent list (by fid)"
13908
13909         # 4) test for entry in root directory
13910         parent=$($LFS path2fid --parents $DIR/f)
13911         echo "$parent" | grep -F "$FID3/f" ||
13912                 error "$FID3/f not returned in parent list"
13913
13914         # 5) test it on root directory
13915         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13916                 error "$MOUNT should not have parents"
13917
13918         # enable xattr caching and check that linkea is correctly updated
13919         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13920         save_lustre_params client "llite.*.xattr_cache" > $save
13921         lctl set_param llite.*.xattr_cache 1
13922
13923         # 6.1) linkea update on rename
13924         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13925
13926         # get parents by fid
13927         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13928         # foo1 should no longer be returned in parent list
13929         echo "$parent" | grep -F "$FID1" &&
13930                 error "$FID1 should no longer be in parent list"
13931         # the new path should appear
13932         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13933                 error "$FID2/$tfile.moved is not in parent list"
13934
13935         # 6.2) linkea update on unlink
13936         rm -f $DIR/$tdir/d/foo2/link
13937         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13938         # foo2/link should no longer be returned in parent list
13939         echo "$parent" | grep -F "$FID2/link" &&
13940                 error "$FID2/link should no longer be in parent list"
13941         true
13942
13943         rm -f $DIR/f
13944         restore_lustre_params < $save
13945         rm -f $save
13946 }
13947 run_test 154f "get parent fids by reading link ea"
13948
13949 test_154g()
13950 {
13951         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13952         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13953            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13954                 skip "Need MDS version at least 2.6.92"
13955
13956         mkdir -p $DIR/$tdir
13957         llapi_fid_test -d $DIR/$tdir
13958 }
13959 run_test 154g "various llapi FID tests"
13960
13961 test_155_small_load() {
13962     local temp=$TMP/$tfile
13963     local file=$DIR/$tfile
13964
13965     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13966         error "dd of=$temp bs=6096 count=1 failed"
13967     cp $temp $file
13968     cancel_lru_locks $OSC
13969     cmp $temp $file || error "$temp $file differ"
13970
13971     $TRUNCATE $temp 6000
13972     $TRUNCATE $file 6000
13973     cmp $temp $file || error "$temp $file differ (truncate1)"
13974
13975     echo "12345" >>$temp
13976     echo "12345" >>$file
13977     cmp $temp $file || error "$temp $file differ (append1)"
13978
13979     echo "12345" >>$temp
13980     echo "12345" >>$file
13981     cmp $temp $file || error "$temp $file differ (append2)"
13982
13983     rm -f $temp $file
13984     true
13985 }
13986
13987 test_155_big_load() {
13988         remote_ost_nodsh && skip "remote OST with nodsh"
13989
13990         local temp=$TMP/$tfile
13991         local file=$DIR/$tfile
13992
13993         free_min_max
13994         local cache_size=$(do_facet ost$((MAXI+1)) \
13995                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13996         local large_file_size=$((cache_size * 2))
13997
13998         echo "OSS cache size: $cache_size KB"
13999         echo "Large file size: $large_file_size KB"
14000
14001         [ $MAXV -le $large_file_size ] &&
14002                 skip_env "max available OST size needs > $large_file_size KB"
14003
14004         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14005
14006         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14007                 error "dd of=$temp bs=$large_file_size count=1k failed"
14008         cp $temp $file
14009         ls -lh $temp $file
14010         cancel_lru_locks osc
14011         cmp $temp $file || error "$temp $file differ"
14012
14013         rm -f $temp $file
14014         true
14015 }
14016
14017 save_writethrough() {
14018         local facets=$(get_facets OST)
14019
14020         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14021 }
14022
14023 test_155a() {
14024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14025
14026         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14027
14028         save_writethrough $p
14029
14030         set_cache read on
14031         set_cache writethrough on
14032         test_155_small_load
14033         restore_lustre_params < $p
14034         rm -f $p
14035 }
14036 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14037
14038 test_155b() {
14039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14040
14041         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14042
14043         save_writethrough $p
14044
14045         set_cache read on
14046         set_cache writethrough off
14047         test_155_small_load
14048         restore_lustre_params < $p
14049         rm -f $p
14050 }
14051 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14052
14053 test_155c() {
14054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14055
14056         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14057
14058         save_writethrough $p
14059
14060         set_cache read off
14061         set_cache writethrough on
14062         test_155_small_load
14063         restore_lustre_params < $p
14064         rm -f $p
14065 }
14066 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14067
14068 test_155d() {
14069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14070
14071         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14072
14073         save_writethrough $p
14074
14075         set_cache read off
14076         set_cache writethrough off
14077         test_155_small_load
14078         restore_lustre_params < $p
14079         rm -f $p
14080 }
14081 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14082
14083 test_155e() {
14084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14085
14086         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14087
14088         save_writethrough $p
14089
14090         set_cache read on
14091         set_cache writethrough on
14092         test_155_big_load
14093         restore_lustre_params < $p
14094         rm -f $p
14095 }
14096 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14097
14098 test_155f() {
14099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14100
14101         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14102
14103         save_writethrough $p
14104
14105         set_cache read on
14106         set_cache writethrough off
14107         test_155_big_load
14108         restore_lustre_params < $p
14109         rm -f $p
14110 }
14111 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14112
14113 test_155g() {
14114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14115
14116         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14117
14118         save_writethrough $p
14119
14120         set_cache read off
14121         set_cache writethrough on
14122         test_155_big_load
14123         restore_lustre_params < $p
14124         rm -f $p
14125 }
14126 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14127
14128 test_155h() {
14129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14130
14131         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14132
14133         save_writethrough $p
14134
14135         set_cache read off
14136         set_cache writethrough off
14137         test_155_big_load
14138         restore_lustre_params < $p
14139         rm -f $p
14140 }
14141 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14142
14143 test_156() {
14144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14145         remote_ost_nodsh && skip "remote OST with nodsh"
14146         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14147                 skip "stats not implemented on old servers"
14148         [ "$ost1_FSTYPE" = "zfs" ] &&
14149                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14150
14151         local CPAGES=3
14152         local BEFORE
14153         local AFTER
14154         local file="$DIR/$tfile"
14155         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14156
14157         save_writethrough $p
14158         roc_hit_init
14159
14160         log "Turn on read and write cache"
14161         set_cache read on
14162         set_cache writethrough on
14163
14164         log "Write data and read it back."
14165         log "Read should be satisfied from the cache."
14166         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14167         BEFORE=$(roc_hit)
14168         cancel_lru_locks osc
14169         cat $file >/dev/null
14170         AFTER=$(roc_hit)
14171         if ! let "AFTER - BEFORE == CPAGES"; then
14172                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14173         else
14174                 log "cache hits: before: $BEFORE, after: $AFTER"
14175         fi
14176
14177         log "Read again; it should be satisfied from the cache."
14178         BEFORE=$AFTER
14179         cancel_lru_locks osc
14180         cat $file >/dev/null
14181         AFTER=$(roc_hit)
14182         if ! let "AFTER - BEFORE == CPAGES"; then
14183                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14184         else
14185                 log "cache hits:: before: $BEFORE, after: $AFTER"
14186         fi
14187
14188         log "Turn off the read cache and turn on the write cache"
14189         set_cache read off
14190         set_cache writethrough on
14191
14192         log "Read again; it should be satisfied from the cache."
14193         BEFORE=$(roc_hit)
14194         cancel_lru_locks osc
14195         cat $file >/dev/null
14196         AFTER=$(roc_hit)
14197         if ! let "AFTER - BEFORE == CPAGES"; then
14198                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14199         else
14200                 log "cache hits:: before: $BEFORE, after: $AFTER"
14201         fi
14202
14203         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14204                 # > 2.12.56 uses pagecache if cached
14205                 log "Read again; it should not be satisfied from the cache."
14206                 BEFORE=$AFTER
14207                 cancel_lru_locks osc
14208                 cat $file >/dev/null
14209                 AFTER=$(roc_hit)
14210                 if ! let "AFTER - BEFORE == 0"; then
14211                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14212                 else
14213                         log "cache hits:: before: $BEFORE, after: $AFTER"
14214                 fi
14215         fi
14216
14217         log "Write data and read it back."
14218         log "Read should be satisfied from the cache."
14219         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14220         BEFORE=$(roc_hit)
14221         cancel_lru_locks osc
14222         cat $file >/dev/null
14223         AFTER=$(roc_hit)
14224         if ! let "AFTER - BEFORE == CPAGES"; then
14225                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14226         else
14227                 log "cache hits:: before: $BEFORE, after: $AFTER"
14228         fi
14229
14230         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14231                 # > 2.12.56 uses pagecache if cached
14232                 log "Read again; it should not be satisfied from the cache."
14233                 BEFORE=$AFTER
14234                 cancel_lru_locks osc
14235                 cat $file >/dev/null
14236                 AFTER=$(roc_hit)
14237                 if ! let "AFTER - BEFORE == 0"; then
14238                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14239                 else
14240                         log "cache hits:: before: $BEFORE, after: $AFTER"
14241                 fi
14242         fi
14243
14244         log "Turn off read and write cache"
14245         set_cache read off
14246         set_cache writethrough off
14247
14248         log "Write data and read it back"
14249         log "It should not be satisfied from the cache."
14250         rm -f $file
14251         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14252         cancel_lru_locks osc
14253         BEFORE=$(roc_hit)
14254         cat $file >/dev/null
14255         AFTER=$(roc_hit)
14256         if ! let "AFTER - BEFORE == 0"; then
14257                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14258         else
14259                 log "cache hits:: before: $BEFORE, after: $AFTER"
14260         fi
14261
14262         log "Turn on the read cache and turn off the write cache"
14263         set_cache read on
14264         set_cache writethrough off
14265
14266         log "Write data and read it back"
14267         log "It should not be satisfied from the cache."
14268         rm -f $file
14269         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14270         BEFORE=$(roc_hit)
14271         cancel_lru_locks osc
14272         cat $file >/dev/null
14273         AFTER=$(roc_hit)
14274         if ! let "AFTER - BEFORE == 0"; then
14275                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14276         else
14277                 log "cache hits:: before: $BEFORE, after: $AFTER"
14278         fi
14279
14280         log "Read again; it should be satisfied from the cache."
14281         BEFORE=$(roc_hit)
14282         cancel_lru_locks osc
14283         cat $file >/dev/null
14284         AFTER=$(roc_hit)
14285         if ! let "AFTER - BEFORE == CPAGES"; then
14286                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14287         else
14288                 log "cache hits:: before: $BEFORE, after: $AFTER"
14289         fi
14290
14291         restore_lustre_params < $p
14292         rm -f $p $file
14293 }
14294 run_test 156 "Verification of tunables"
14295
14296 test_160a() {
14297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14298         remote_mds_nodsh && skip "remote MDS with nodsh"
14299         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14300                 skip "Need MDS version at least 2.2.0"
14301
14302         changelog_register || error "changelog_register failed"
14303         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14304         changelog_users $SINGLEMDS | grep -q $cl_user ||
14305                 error "User $cl_user not found in changelog_users"
14306
14307         # change something
14308         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14309         changelog_clear 0 || error "changelog_clear failed"
14310         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14311         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14312         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14313         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14314         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14315         rm $DIR/$tdir/pics/desktop.jpg
14316
14317         changelog_dump | tail -10
14318
14319         echo "verifying changelog mask"
14320         changelog_chmask "-MKDIR"
14321         changelog_chmask "-CLOSE"
14322
14323         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14324         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14325
14326         changelog_chmask "+MKDIR"
14327         changelog_chmask "+CLOSE"
14328
14329         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14330         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14331
14332         changelog_dump | tail -10
14333         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14334         CLOSES=$(changelog_dump | grep -c "CLOSE")
14335         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14336         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14337
14338         # verify contents
14339         echo "verifying target fid"
14340         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14341         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14342         [ "$fidc" == "$fidf" ] ||
14343                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14344         echo "verifying parent fid"
14345         # The FID returned from the Changelog may be the directory shard on
14346         # a different MDT, and not the FID returned by path2fid on the parent.
14347         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14348         # since this is what will matter when recreating this file in the tree.
14349         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14350         local pathp=$($LFS fid2path $MOUNT "$fidp")
14351         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14352                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14353
14354         echo "getting records for $cl_user"
14355         changelog_users $SINGLEMDS
14356         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14357         local nclr=3
14358         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14359                 error "changelog_clear failed"
14360         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14361         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14362         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14363                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14364
14365         local min0_rec=$(changelog_users $SINGLEMDS |
14366                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14367         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14368                           awk '{ print $1; exit; }')
14369
14370         changelog_dump | tail -n 5
14371         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14372         [ $first_rec == $((min0_rec + 1)) ] ||
14373                 error "first index should be $min0_rec + 1 not $first_rec"
14374
14375         # LU-3446 changelog index reset on MDT restart
14376         local cur_rec1=$(changelog_users $SINGLEMDS |
14377                          awk '/^current.index:/ { print $NF }')
14378         changelog_clear 0 ||
14379                 error "clear all changelog records for $cl_user failed"
14380         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14381         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14382                 error "Fail to start $SINGLEMDS"
14383         local cur_rec2=$(changelog_users $SINGLEMDS |
14384                          awk '/^current.index:/ { print $NF }')
14385         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14386         [ $cur_rec1 == $cur_rec2 ] ||
14387                 error "current index should be $cur_rec1 not $cur_rec2"
14388
14389         echo "verifying users from this test are deregistered"
14390         changelog_deregister || error "changelog_deregister failed"
14391         changelog_users $SINGLEMDS | grep -q $cl_user &&
14392                 error "User '$cl_user' still in changelog_users"
14393
14394         # lctl get_param -n mdd.*.changelog_users
14395         # current index: 144
14396         # ID    index (idle seconds)
14397         # cl3   144 (2)
14398         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14399                 # this is the normal case where all users were deregistered
14400                 # make sure no new records are added when no users are present
14401                 local last_rec1=$(changelog_users $SINGLEMDS |
14402                                   awk '/^current.index:/ { print $NF }')
14403                 touch $DIR/$tdir/chloe
14404                 local last_rec2=$(changelog_users $SINGLEMDS |
14405                                   awk '/^current.index:/ { print $NF }')
14406                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14407                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14408         else
14409                 # any changelog users must be leftovers from a previous test
14410                 changelog_users $SINGLEMDS
14411                 echo "other changelog users; can't verify off"
14412         fi
14413 }
14414 run_test 160a "changelog sanity"
14415
14416 test_160b() { # LU-3587
14417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14418         remote_mds_nodsh && skip "remote MDS with nodsh"
14419         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14420                 skip "Need MDS version at least 2.2.0"
14421
14422         changelog_register || error "changelog_register failed"
14423         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14424         changelog_users $SINGLEMDS | grep -q $cl_user ||
14425                 error "User '$cl_user' not found in changelog_users"
14426
14427         local longname1=$(str_repeat a 255)
14428         local longname2=$(str_repeat b 255)
14429
14430         cd $DIR
14431         echo "creating very long named file"
14432         touch $longname1 || error "create of '$longname1' failed"
14433         echo "renaming very long named file"
14434         mv $longname1 $longname2
14435
14436         changelog_dump | grep RENME | tail -n 5
14437         rm -f $longname2
14438 }
14439 run_test 160b "Verify that very long rename doesn't crash in changelog"
14440
14441 test_160c() {
14442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14443         remote_mds_nodsh && skip "remote MDS with nodsh"
14444
14445         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14446                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14447                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14448                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14449
14450         local rc=0
14451
14452         # Registration step
14453         changelog_register || error "changelog_register failed"
14454
14455         rm -rf $DIR/$tdir
14456         mkdir -p $DIR/$tdir
14457         $MCREATE $DIR/$tdir/foo_160c
14458         changelog_chmask "-TRUNC"
14459         $TRUNCATE $DIR/$tdir/foo_160c 200
14460         changelog_chmask "+TRUNC"
14461         $TRUNCATE $DIR/$tdir/foo_160c 199
14462         changelog_dump | tail -n 5
14463         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14464         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14465 }
14466 run_test 160c "verify that changelog log catch the truncate event"
14467
14468 test_160d() {
14469         remote_mds_nodsh && skip "remote MDS with nodsh"
14470         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14472         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14473                 skip "Need MDS version at least 2.7.60"
14474
14475         # Registration step
14476         changelog_register || error "changelog_register failed"
14477
14478         mkdir -p $DIR/$tdir/migrate_dir
14479         changelog_clear 0 || error "changelog_clear failed"
14480
14481         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14482         changelog_dump | tail -n 5
14483         local migrates=$(changelog_dump | grep -c "MIGRT")
14484         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14485 }
14486 run_test 160d "verify that changelog log catch the migrate event"
14487
14488 test_160e() {
14489         remote_mds_nodsh && skip "remote MDS with nodsh"
14490
14491         # Create a user
14492         changelog_register || error "changelog_register failed"
14493
14494         # Delete a future user (expect fail)
14495         local MDT0=$(facet_svc $SINGLEMDS)
14496         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14497         local rc=$?
14498
14499         if [ $rc -eq 0 ]; then
14500                 error "Deleted non-existant user cl77"
14501         elif [ $rc -ne 2 ]; then
14502                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14503         fi
14504
14505         # Clear to a bad index (1 billion should be safe)
14506         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14507         rc=$?
14508
14509         if [ $rc -eq 0 ]; then
14510                 error "Successfully cleared to invalid CL index"
14511         elif [ $rc -ne 22 ]; then
14512                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14513         fi
14514 }
14515 run_test 160e "changelog negative testing (should return errors)"
14516
14517 test_160f() {
14518         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14519         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14520                 skip "Need MDS version at least 2.10.56"
14521
14522         local mdts=$(comma_list $(mdts_nodes))
14523
14524         # Create a user
14525         changelog_register || error "first changelog_register failed"
14526         changelog_register || error "second changelog_register failed"
14527         local cl_users
14528         declare -A cl_user1
14529         declare -A cl_user2
14530         local user_rec1
14531         local user_rec2
14532         local i
14533
14534         # generate some changelog records to accumulate on each MDT
14535         # use fnv1a because created files should be evenly distributed
14536         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14537                 error "test_mkdir $tdir failed"
14538         log "$(date +%s): creating first files"
14539         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14540                 error "create $DIR/$tdir/$tfile failed"
14541
14542         # check changelogs have been generated
14543         local start=$SECONDS
14544         local idle_time=$((MDSCOUNT * 5 + 5))
14545         local nbcl=$(changelog_dump | wc -l)
14546         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14547
14548         for param in "changelog_max_idle_time=$idle_time" \
14549                      "changelog_gc=1" \
14550                      "changelog_min_gc_interval=2" \
14551                      "changelog_min_free_cat_entries=3"; do
14552                 local MDT0=$(facet_svc $SINGLEMDS)
14553                 local var="${param%=*}"
14554                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14555
14556                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14557                 do_nodes $mdts $LCTL set_param mdd.*.$param
14558         done
14559
14560         # force cl_user2 to be idle (1st part), but also cancel the
14561         # cl_user1 records so that it is not evicted later in the test.
14562         local sleep1=$((idle_time / 2))
14563         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14564         sleep $sleep1
14565
14566         # simulate changelog catalog almost full
14567         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14568         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14569
14570         for i in $(seq $MDSCOUNT); do
14571                 cl_users=(${CL_USERS[mds$i]})
14572                 cl_user1[mds$i]="${cl_users[0]}"
14573                 cl_user2[mds$i]="${cl_users[1]}"
14574
14575                 [ -n "${cl_user1[mds$i]}" ] ||
14576                         error "mds$i: no user registered"
14577                 [ -n "${cl_user2[mds$i]}" ] ||
14578                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14579
14580                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14581                 [ -n "$user_rec1" ] ||
14582                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14583                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14584                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14585                 [ -n "$user_rec2" ] ||
14586                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14587                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14588                      "$user_rec1 + 2 == $user_rec2"
14589                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14590                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14591                               "$user_rec1 + 2, but is $user_rec2"
14592                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14593                 [ -n "$user_rec2" ] ||
14594                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14595                 [ $user_rec1 == $user_rec2 ] ||
14596                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14597                               "$user_rec1, but is $user_rec2"
14598         done
14599
14600         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14601         local sleep2=$((idle_time - (SECONDS - start) + 1))
14602         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14603         sleep $sleep2
14604
14605         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14606         # cl_user1 should be OK because it recently processed records.
14607         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14608         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14609                 error "create $DIR/$tdir/${tfile}b failed"
14610
14611         # ensure gc thread is done
14612         for i in $(mdts_nodes); do
14613                 wait_update $i \
14614                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14615                         error "$i: GC-thread not done"
14616         done
14617
14618         local first_rec
14619         for i in $(seq $MDSCOUNT); do
14620                 # check cl_user1 still registered
14621                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14622                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14623                 # check cl_user2 unregistered
14624                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14625                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14626
14627                 # check changelogs are present and starting at $user_rec1 + 1
14628                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14629                 [ -n "$user_rec1" ] ||
14630                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14631                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14632                             awk '{ print $1; exit; }')
14633
14634                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14635                 [ $((user_rec1 + 1)) == $first_rec ] ||
14636                         error "mds$i: first index should be $user_rec1 + 1, " \
14637                               "but is $first_rec"
14638         done
14639 }
14640 run_test 160f "changelog garbage collect (timestamped users)"
14641
14642 test_160g() {
14643         remote_mds_nodsh && skip "remote MDS with nodsh"
14644         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14645                 skip "Need MDS version at least 2.10.56"
14646
14647         local mdts=$(comma_list $(mdts_nodes))
14648
14649         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14650         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14651
14652         # Create a user
14653         changelog_register || error "first changelog_register failed"
14654         changelog_register || error "second changelog_register failed"
14655         local cl_users
14656         declare -A cl_user1
14657         declare -A cl_user2
14658         local user_rec1
14659         local user_rec2
14660         local i
14661
14662         # generate some changelog records to accumulate on each MDT
14663         # use fnv1a because created files should be evenly distributed
14664         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14665                 error "mkdir $tdir failed"
14666         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14667                 error "create $DIR/$tdir/$tfile failed"
14668
14669         # check changelogs have been generated
14670         local nbcl=$(changelog_dump | wc -l)
14671         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14672
14673         # reduce the max_idle_indexes value to make sure we exceed it
14674         max_ndx=$((nbcl / 2 - 1))
14675
14676         for param in "changelog_max_idle_indexes=$max_ndx" \
14677                      "changelog_gc=1" \
14678                      "changelog_min_gc_interval=2" \
14679                      "changelog_min_free_cat_entries=3"; do
14680                 local MDT0=$(facet_svc $SINGLEMDS)
14681                 local var="${param%=*}"
14682                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14683
14684                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14685                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14686                         error "unable to set mdd.*.$param"
14687         done
14688
14689         # simulate changelog catalog almost full
14690         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14691         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14692
14693         for i in $(seq $MDSCOUNT); do
14694                 cl_users=(${CL_USERS[mds$i]})
14695                 cl_user1[mds$i]="${cl_users[0]}"
14696                 cl_user2[mds$i]="${cl_users[1]}"
14697
14698                 [ -n "${cl_user1[mds$i]}" ] ||
14699                         error "mds$i: no user registered"
14700                 [ -n "${cl_user2[mds$i]}" ] ||
14701                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14702
14703                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14704                 [ -n "$user_rec1" ] ||
14705                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14706                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14707                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14708                 [ -n "$user_rec2" ] ||
14709                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14710                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14711                      "$user_rec1 + 2 == $user_rec2"
14712                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14713                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14714                               "$user_rec1 + 2, but is $user_rec2"
14715                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14716                 [ -n "$user_rec2" ] ||
14717                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14718                 [ $user_rec1 == $user_rec2 ] ||
14719                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14720                               "$user_rec1, but is $user_rec2"
14721         done
14722
14723         # ensure we are past the previous changelog_min_gc_interval set above
14724         sleep 2
14725
14726         # generate one more changelog to trigger fail_loc
14727         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14728                 error "create $DIR/$tdir/${tfile}bis failed"
14729
14730         # ensure gc thread is done
14731         for i in $(mdts_nodes); do
14732                 wait_update $i \
14733                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14734                         error "$i: GC-thread not done"
14735         done
14736
14737         local first_rec
14738         for i in $(seq $MDSCOUNT); do
14739                 # check cl_user1 still registered
14740                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14741                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14742                 # check cl_user2 unregistered
14743                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14744                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14745
14746                 # check changelogs are present and starting at $user_rec1 + 1
14747                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14748                 [ -n "$user_rec1" ] ||
14749                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14750                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14751                             awk '{ print $1; exit; }')
14752
14753                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14754                 [ $((user_rec1 + 1)) == $first_rec ] ||
14755                         error "mds$i: first index should be $user_rec1 + 1, " \
14756                               "but is $first_rec"
14757         done
14758 }
14759 run_test 160g "changelog garbage collect (old users)"
14760
14761 test_160h() {
14762         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14763         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14764                 skip "Need MDS version at least 2.10.56"
14765
14766         local mdts=$(comma_list $(mdts_nodes))
14767
14768         # Create a user
14769         changelog_register || error "first changelog_register failed"
14770         changelog_register || error "second changelog_register failed"
14771         local cl_users
14772         declare -A cl_user1
14773         declare -A cl_user2
14774         local user_rec1
14775         local user_rec2
14776         local i
14777
14778         # generate some changelog records to accumulate on each MDT
14779         # use fnv1a because created files should be evenly distributed
14780         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14781                 error "test_mkdir $tdir failed"
14782         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14783                 error "create $DIR/$tdir/$tfile failed"
14784
14785         # check changelogs have been generated
14786         local nbcl=$(changelog_dump | wc -l)
14787         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14788
14789         for param in "changelog_max_idle_time=10" \
14790                      "changelog_gc=1" \
14791                      "changelog_min_gc_interval=2"; do
14792                 local MDT0=$(facet_svc $SINGLEMDS)
14793                 local var="${param%=*}"
14794                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14795
14796                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14797                 do_nodes $mdts $LCTL set_param mdd.*.$param
14798         done
14799
14800         # force cl_user2 to be idle (1st part)
14801         sleep 9
14802
14803         for i in $(seq $MDSCOUNT); do
14804                 cl_users=(${CL_USERS[mds$i]})
14805                 cl_user1[mds$i]="${cl_users[0]}"
14806                 cl_user2[mds$i]="${cl_users[1]}"
14807
14808                 [ -n "${cl_user1[mds$i]}" ] ||
14809                         error "mds$i: no user registered"
14810                 [ -n "${cl_user2[mds$i]}" ] ||
14811                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14812
14813                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14814                 [ -n "$user_rec1" ] ||
14815                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14816                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14817                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14818                 [ -n "$user_rec2" ] ||
14819                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14820                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14821                      "$user_rec1 + 2 == $user_rec2"
14822                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14823                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14824                               "$user_rec1 + 2, but is $user_rec2"
14825                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14826                 [ -n "$user_rec2" ] ||
14827                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14828                 [ $user_rec1 == $user_rec2 ] ||
14829                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14830                               "$user_rec1, but is $user_rec2"
14831         done
14832
14833         # force cl_user2 to be idle (2nd part) and to reach
14834         # changelog_max_idle_time
14835         sleep 2
14836
14837         # force each GC-thread start and block then
14838         # one per MDT/MDD, set fail_val accordingly
14839         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14840         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14841
14842         # generate more changelogs to trigger fail_loc
14843         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14844                 error "create $DIR/$tdir/${tfile}bis failed"
14845
14846         # stop MDT to stop GC-thread, should be done in back-ground as it will
14847         # block waiting for the thread to be released and exit
14848         declare -A stop_pids
14849         for i in $(seq $MDSCOUNT); do
14850                 stop mds$i &
14851                 stop_pids[mds$i]=$!
14852         done
14853
14854         for i in $(mdts_nodes); do
14855                 local facet
14856                 local nb=0
14857                 local facets=$(facets_up_on_host $i)
14858
14859                 for facet in ${facets//,/ }; do
14860                         if [[ $facet == mds* ]]; then
14861                                 nb=$((nb + 1))
14862                         fi
14863                 done
14864                 # ensure each MDS's gc threads are still present and all in "R"
14865                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14866                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14867                         error "$i: expected $nb GC-thread"
14868                 wait_update $i \
14869                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14870                         "R" 20 ||
14871                         error "$i: GC-thread not found in R-state"
14872                 # check umounts of each MDT on MDS have reached kthread_stop()
14873                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14874                         error "$i: expected $nb umount"
14875                 wait_update $i \
14876                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14877                         error "$i: umount not found in D-state"
14878         done
14879
14880         # release all GC-threads
14881         do_nodes $mdts $LCTL set_param fail_loc=0
14882
14883         # wait for MDT stop to complete
14884         for i in $(seq $MDSCOUNT); do
14885                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14886         done
14887
14888         # XXX
14889         # may try to check if any orphan changelog records are present
14890         # via ldiskfs/zfs and llog_reader...
14891
14892         # re-start/mount MDTs
14893         for i in $(seq $MDSCOUNT); do
14894                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14895                         error "Fail to start mds$i"
14896         done
14897
14898         local first_rec
14899         for i in $(seq $MDSCOUNT); do
14900                 # check cl_user1 still registered
14901                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14902                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14903                 # check cl_user2 unregistered
14904                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14905                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14906
14907                 # check changelogs are present and starting at $user_rec1 + 1
14908                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14909                 [ -n "$user_rec1" ] ||
14910                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14911                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14912                             awk '{ print $1; exit; }')
14913
14914                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14915                 [ $((user_rec1 + 1)) == $first_rec ] ||
14916                         error "mds$i: first index should be $user_rec1 + 1, " \
14917                               "but is $first_rec"
14918         done
14919 }
14920 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14921               "during mount"
14922
14923 test_160i() {
14924
14925         local mdts=$(comma_list $(mdts_nodes))
14926
14927         changelog_register || error "first changelog_register failed"
14928
14929         # generate some changelog records to accumulate on each MDT
14930         # use fnv1a because created files should be evenly distributed
14931         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14932                 error "mkdir $tdir failed"
14933         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14934                 error "create $DIR/$tdir/$tfile failed"
14935
14936         # check changelogs have been generated
14937         local nbcl=$(changelog_dump | wc -l)
14938         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14939
14940         # simulate race between register and unregister
14941         # XXX as fail_loc is set per-MDS, with DNE configs the race
14942         # simulation will only occur for one MDT per MDS and for the
14943         # others the normal race scenario will take place
14944         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14945         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14946         do_nodes $mdts $LCTL set_param fail_val=1
14947
14948         # unregister 1st user
14949         changelog_deregister &
14950         local pid1=$!
14951         # wait some time for deregister work to reach race rdv
14952         sleep 2
14953         # register 2nd user
14954         changelog_register || error "2nd user register failed"
14955
14956         wait $pid1 || error "1st user deregister failed"
14957
14958         local i
14959         local last_rec
14960         declare -A LAST_REC
14961         for i in $(seq $MDSCOUNT); do
14962                 if changelog_users mds$i | grep "^cl"; then
14963                         # make sure new records are added with one user present
14964                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14965                                           awk '/^current.index:/ { print $NF }')
14966                 else
14967                         error "mds$i has no user registered"
14968                 fi
14969         done
14970
14971         # generate more changelog records to accumulate on each MDT
14972         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14973                 error "create $DIR/$tdir/${tfile}bis failed"
14974
14975         for i in $(seq $MDSCOUNT); do
14976                 last_rec=$(changelog_users $SINGLEMDS |
14977                            awk '/^current.index:/ { print $NF }')
14978                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14979                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14980                         error "changelogs are off on mds$i"
14981         done
14982 }
14983 run_test 160i "changelog user register/unregister race"
14984
14985 test_160j() {
14986         remote_mds_nodsh && skip "remote MDS with nodsh"
14987         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14988                 skip "Need MDS version at least 2.12.56"
14989
14990         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14991         stack_trap "umount $MOUNT2" EXIT
14992
14993         changelog_register || error "first changelog_register failed"
14994         stack_trap "changelog_deregister" EXIT
14995
14996         # generate some changelog
14997         # use fnv1a because created files should be evenly distributed
14998         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14999                 error "mkdir $tdir failed"
15000         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15001                 error "create $DIR/$tdir/${tfile}bis failed"
15002
15003         # open the changelog device
15004         exec 3>/dev/changelog-$FSNAME-MDT0000
15005         stack_trap "exec 3>&-" EXIT
15006         exec 4</dev/changelog-$FSNAME-MDT0000
15007         stack_trap "exec 4<&-" EXIT
15008
15009         # umount the first lustre mount
15010         umount $MOUNT
15011         stack_trap "mount_client $MOUNT" EXIT
15012
15013         # read changelog
15014         cat <&4 >/dev/null || error "read changelog failed"
15015
15016         # clear changelog
15017         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15018         changelog_users $SINGLEMDS | grep -q $cl_user ||
15019                 error "User $cl_user not found in changelog_users"
15020
15021         printf 'clear:'$cl_user':0' >&3
15022 }
15023 run_test 160j "client can be umounted  while its chanangelog is being used"
15024
15025 test_160k() {
15026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15027         remote_mds_nodsh && skip "remote MDS with nodsh"
15028
15029         mkdir -p $DIR/$tdir/1/1
15030
15031         changelog_register || error "changelog_register failed"
15032         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15033
15034         changelog_users $SINGLEMDS | grep -q $cl_user ||
15035                 error "User '$cl_user' not found in changelog_users"
15036 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15037         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15038         rmdir $DIR/$tdir/1/1 & sleep 1
15039         mkdir $DIR/$tdir/2
15040         touch $DIR/$tdir/2/2
15041         rm -rf $DIR/$tdir/2
15042
15043         wait
15044         sleep 4
15045
15046         changelog_dump | grep rmdir || error "rmdir not recorded"
15047
15048         rm -rf $DIR/$tdir
15049         changelog_deregister
15050 }
15051 run_test 160k "Verify that changelog records are not lost"
15052
15053 # Verifies that a file passed as a parameter has recently had an operation
15054 # performed on it that has generated an MTIME changelog which contains the
15055 # correct parent FID. As files might reside on a different MDT from the
15056 # parent directory in DNE configurations, the FIDs are translated to paths
15057 # before being compared, which should be identical
15058 compare_mtime_changelog() {
15059         local file="${1}"
15060         local mdtidx
15061         local mtime
15062         local cl_fid
15063         local pdir
15064         local dir
15065
15066         mdtidx=$($LFS getstripe --mdt-index $file)
15067         mdtidx=$(printf "%04x" $mdtidx)
15068
15069         # Obtain the parent FID from the MTIME changelog
15070         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15071         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15072
15073         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15074         [ -z "$cl_fid" ] && error "parent FID not present"
15075
15076         # Verify that the path for the parent FID is the same as the path for
15077         # the test directory
15078         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15079
15080         dir=$(dirname $1)
15081
15082         [[ "${pdir%/}" == "$dir" ]] ||
15083                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15084 }
15085
15086 test_160l() {
15087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15088
15089         remote_mds_nodsh && skip "remote MDS with nodsh"
15090         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15091                 skip "Need MDS version at least 2.13.55"
15092
15093         local cl_user
15094
15095         changelog_register || error "changelog_register failed"
15096         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15097
15098         changelog_users $SINGLEMDS | grep -q $cl_user ||
15099                 error "User '$cl_user' not found in changelog_users"
15100
15101         # Clear some types so that MTIME changelogs are generated
15102         changelog_chmask "-CREAT"
15103         changelog_chmask "-CLOSE"
15104
15105         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15106
15107         # Test CL_MTIME during setattr
15108         touch $DIR/$tdir/$tfile
15109         compare_mtime_changelog $DIR/$tdir/$tfile
15110
15111         # Test CL_MTIME during close
15112         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15113                 error "cannot create file $DIR/$tdir/${tfile}_2"
15114         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15115 }
15116 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15117
15118 test_161a() {
15119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15120
15121         test_mkdir -c1 $DIR/$tdir
15122         cp /etc/hosts $DIR/$tdir/$tfile
15123         test_mkdir -c1 $DIR/$tdir/foo1
15124         test_mkdir -c1 $DIR/$tdir/foo2
15125         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15126         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15127         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15128         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15129         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15130         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15131                 $LFS fid2path $DIR $FID
15132                 error "bad link ea"
15133         fi
15134         # middle
15135         rm $DIR/$tdir/foo2/zachary
15136         # last
15137         rm $DIR/$tdir/foo2/thor
15138         # first
15139         rm $DIR/$tdir/$tfile
15140         # rename
15141         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15142         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15143                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15144         rm $DIR/$tdir/foo2/maggie
15145
15146         # overflow the EA
15147         local longname=$tfile.avg_len_is_thirty_two_
15148         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15149                 error_noexit 'failed to unlink many hardlinks'" EXIT
15150         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15151                 error "failed to hardlink many files"
15152         links=$($LFS fid2path $DIR $FID | wc -l)
15153         echo -n "${links}/1000 links in link EA"
15154         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15155 }
15156 run_test 161a "link ea sanity"
15157
15158 test_161b() {
15159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15160         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15161
15162         local MDTIDX=1
15163         local remote_dir=$DIR/$tdir/remote_dir
15164
15165         mkdir -p $DIR/$tdir
15166         $LFS mkdir -i $MDTIDX $remote_dir ||
15167                 error "create remote directory failed"
15168
15169         cp /etc/hosts $remote_dir/$tfile
15170         mkdir -p $remote_dir/foo1
15171         mkdir -p $remote_dir/foo2
15172         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15173         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15174         ln $remote_dir/$tfile $remote_dir/foo1/luna
15175         ln $remote_dir/$tfile $remote_dir/foo2/thor
15176
15177         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15178                      tr -d ']')
15179         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15180                 $LFS fid2path $DIR $FID
15181                 error "bad link ea"
15182         fi
15183         # middle
15184         rm $remote_dir/foo2/zachary
15185         # last
15186         rm $remote_dir/foo2/thor
15187         # first
15188         rm $remote_dir/$tfile
15189         # rename
15190         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15191         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15192         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15193                 $LFS fid2path $DIR $FID
15194                 error "bad link rename"
15195         fi
15196         rm $remote_dir/foo2/maggie
15197
15198         # overflow the EA
15199         local longname=filename_avg_len_is_thirty_two_
15200         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15201                 error "failed to hardlink many files"
15202         links=$($LFS fid2path $DIR $FID | wc -l)
15203         echo -n "${links}/1000 links in link EA"
15204         [[ ${links} -gt 60 ]] ||
15205                 error "expected at least 60 links in link EA"
15206         unlinkmany $remote_dir/foo2/$longname 1000 ||
15207         error "failed to unlink many hardlinks"
15208 }
15209 run_test 161b "link ea sanity under remote directory"
15210
15211 test_161c() {
15212         remote_mds_nodsh && skip "remote MDS with nodsh"
15213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15214         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15215                 skip "Need MDS version at least 2.1.5"
15216
15217         # define CLF_RENAME_LAST 0x0001
15218         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15219         changelog_register || error "changelog_register failed"
15220
15221         rm -rf $DIR/$tdir
15222         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15223         touch $DIR/$tdir/foo_161c
15224         touch $DIR/$tdir/bar_161c
15225         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15226         changelog_dump | grep RENME | tail -n 5
15227         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15228         changelog_clear 0 || error "changelog_clear failed"
15229         if [ x$flags != "x0x1" ]; then
15230                 error "flag $flags is not 0x1"
15231         fi
15232
15233         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15234         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15235         touch $DIR/$tdir/foo_161c
15236         touch $DIR/$tdir/bar_161c
15237         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15238         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15239         changelog_dump | grep RENME | tail -n 5
15240         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15241         changelog_clear 0 || error "changelog_clear failed"
15242         if [ x$flags != "x0x0" ]; then
15243                 error "flag $flags is not 0x0"
15244         fi
15245         echo "rename overwrite a target having nlink > 1," \
15246                 "changelog record has flags of $flags"
15247
15248         # rename doesn't overwrite a target (changelog flag 0x0)
15249         touch $DIR/$tdir/foo_161c
15250         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15251         changelog_dump | grep RENME | tail -n 5
15252         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15253         changelog_clear 0 || error "changelog_clear failed"
15254         if [ x$flags != "x0x0" ]; then
15255                 error "flag $flags is not 0x0"
15256         fi
15257         echo "rename doesn't overwrite a target," \
15258                 "changelog record has flags of $flags"
15259
15260         # define CLF_UNLINK_LAST 0x0001
15261         # unlink a file having nlink = 1 (changelog flag 0x1)
15262         rm -f $DIR/$tdir/foo2_161c
15263         changelog_dump | grep UNLNK | tail -n 5
15264         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15265         changelog_clear 0 || error "changelog_clear failed"
15266         if [ x$flags != "x0x1" ]; then
15267                 error "flag $flags is not 0x1"
15268         fi
15269         echo "unlink a file having nlink = 1," \
15270                 "changelog record has flags of $flags"
15271
15272         # unlink a file having nlink > 1 (changelog flag 0x0)
15273         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15274         rm -f $DIR/$tdir/foobar_161c
15275         changelog_dump | grep UNLNK | tail -n 5
15276         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15277         changelog_clear 0 || error "changelog_clear failed"
15278         if [ x$flags != "x0x0" ]; then
15279                 error "flag $flags is not 0x0"
15280         fi
15281         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15282 }
15283 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15284
15285 test_161d() {
15286         remote_mds_nodsh && skip "remote MDS with nodsh"
15287         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15288
15289         local pid
15290         local fid
15291
15292         changelog_register || error "changelog_register failed"
15293
15294         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15295         # interfer with $MOUNT/.lustre/fid/ access
15296         mkdir $DIR/$tdir
15297         [[ $? -eq 0 ]] || error "mkdir failed"
15298
15299         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15300         $LCTL set_param fail_loc=0x8000140c
15301         # 5s pause
15302         $LCTL set_param fail_val=5
15303
15304         # create file
15305         echo foofoo > $DIR/$tdir/$tfile &
15306         pid=$!
15307
15308         # wait for create to be delayed
15309         sleep 2
15310
15311         ps -p $pid
15312         [[ $? -eq 0 ]] || error "create should be blocked"
15313
15314         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15315         stack_trap "rm -f $tempfile"
15316         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15317         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15318         # some delay may occur during ChangeLog publishing and file read just
15319         # above, that could allow file write to happen finally
15320         [[ -s $tempfile ]] && echo "file should be empty"
15321
15322         $LCTL set_param fail_loc=0
15323
15324         wait $pid
15325         [[ $? -eq 0 ]] || error "create failed"
15326 }
15327 run_test 161d "create with concurrent .lustre/fid access"
15328
15329 check_path() {
15330         local expected="$1"
15331         shift
15332         local fid="$2"
15333
15334         local path
15335         path=$($LFS fid2path "$@")
15336         local rc=$?
15337
15338         if [ $rc -ne 0 ]; then
15339                 error "path looked up of '$expected' failed: rc=$rc"
15340         elif [ "$path" != "$expected" ]; then
15341                 error "path looked up '$path' instead of '$expected'"
15342         else
15343                 echo "FID '$fid' resolves to path '$path' as expected"
15344         fi
15345 }
15346
15347 test_162a() { # was test_162
15348         test_mkdir -p -c1 $DIR/$tdir/d2
15349         touch $DIR/$tdir/d2/$tfile
15350         touch $DIR/$tdir/d2/x1
15351         touch $DIR/$tdir/d2/x2
15352         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15353         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15354         # regular file
15355         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15356         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15357
15358         # softlink
15359         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15360         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15361         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15362
15363         # softlink to wrong file
15364         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15365         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15366         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15367
15368         # hardlink
15369         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15370         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15371         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15372         # fid2path dir/fsname should both work
15373         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15374         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15375
15376         # hardlink count: check that there are 2 links
15377         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15378         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15379
15380         # hardlink indexing: remove the first link
15381         rm $DIR/$tdir/d2/p/q/r/hlink
15382         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15383 }
15384 run_test 162a "path lookup sanity"
15385
15386 test_162b() {
15387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15389
15390         mkdir $DIR/$tdir
15391         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15392                                 error "create striped dir failed"
15393
15394         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15395                                         tail -n 1 | awk '{print $2}')
15396         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15397
15398         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15399         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15400
15401         # regular file
15402         for ((i=0;i<5;i++)); do
15403                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15404                         error "get fid for f$i failed"
15405                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15406
15407                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15408                         error "get fid for d$i failed"
15409                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15410         done
15411
15412         return 0
15413 }
15414 run_test 162b "striped directory path lookup sanity"
15415
15416 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15417 test_162c() {
15418         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15419                 skip "Need MDS version at least 2.7.51"
15420
15421         local lpath=$tdir.local
15422         local rpath=$tdir.remote
15423
15424         test_mkdir $DIR/$lpath
15425         test_mkdir $DIR/$rpath
15426
15427         for ((i = 0; i <= 101; i++)); do
15428                 lpath="$lpath/$i"
15429                 mkdir $DIR/$lpath
15430                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15431                         error "get fid for local directory $DIR/$lpath failed"
15432                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15433
15434                 rpath="$rpath/$i"
15435                 test_mkdir $DIR/$rpath
15436                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15437                         error "get fid for remote directory $DIR/$rpath failed"
15438                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15439         done
15440
15441         return 0
15442 }
15443 run_test 162c "fid2path works with paths 100 or more directories deep"
15444
15445 oalr_event_count() {
15446         local event="${1}"
15447         local trace="${2}"
15448
15449         awk -v name="${FSNAME}-OST0000" \
15450             -v event="${event}" \
15451             '$1 == "TRACE" && $2 == event && $3 == name' \
15452             "${trace}" |
15453         wc -l
15454 }
15455
15456 oalr_expect_event_count() {
15457         local event="${1}"
15458         local trace="${2}"
15459         local expect="${3}"
15460         local count
15461
15462         count=$(oalr_event_count "${event}" "${trace}")
15463         if ((count == expect)); then
15464                 return 0
15465         fi
15466
15467         error_noexit "${event} event count was '${count}', expected ${expect}"
15468         cat "${trace}" >&2
15469         exit 1
15470 }
15471
15472 cleanup_165() {
15473         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15474         stop ost1
15475         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15476 }
15477
15478 setup_165() {
15479         sync # Flush previous IOs so we can count log entries.
15480         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15481         stack_trap cleanup_165 EXIT
15482 }
15483
15484 test_165a() {
15485         local trace="/tmp/${tfile}.trace"
15486         local rc
15487         local count
15488
15489         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15490         setup_165
15491         sleep 5
15492
15493         do_facet ost1 ofd_access_log_reader --list
15494         stop ost1
15495
15496         do_facet ost1 killall -TERM ofd_access_log_reader
15497         wait
15498         rc=$?
15499
15500         if ((rc != 0)); then
15501                 error "ofd_access_log_reader exited with rc = '${rc}'"
15502         fi
15503
15504         # Parse trace file for discovery events:
15505         oalr_expect_event_count alr_log_add "${trace}" 1
15506         oalr_expect_event_count alr_log_eof "${trace}" 1
15507         oalr_expect_event_count alr_log_free "${trace}" 1
15508 }
15509 run_test 165a "ofd access log discovery"
15510
15511 test_165b() {
15512         local trace="/tmp/${tfile}.trace"
15513         local file="${DIR}/${tfile}"
15514         local pfid1
15515         local pfid2
15516         local -a entry
15517         local rc
15518         local count
15519         local size
15520         local flags
15521
15522         setup_165
15523
15524         lfs setstripe -c 1 -i 0 "${file}"
15525         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15526         do_facet ost1 ofd_access_log_reader --list
15527
15528         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15529         sleep 5
15530         do_facet ost1 killall -TERM ofd_access_log_reader
15531         wait
15532         rc=$?
15533
15534         if ((rc != 0)); then
15535                 error "ofd_access_log_reader exited with rc = '${rc}'"
15536         fi
15537
15538         oalr_expect_event_count alr_log_entry "${trace}" 1
15539
15540         pfid1=$($LFS path2fid "${file}")
15541
15542         # 1     2             3   4    5     6   7    8    9     10
15543         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15544         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15545
15546         echo "entry = '${entry[*]}'" >&2
15547
15548         pfid2=${entry[4]}
15549         if [[ "${pfid1}" != "${pfid2}" ]]; then
15550                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15551         fi
15552
15553         size=${entry[8]}
15554         if ((size != 1048576)); then
15555                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15556         fi
15557
15558         flags=${entry[10]}
15559         if [[ "${flags}" != "w" ]]; then
15560                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15561         fi
15562
15563         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15564         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15565         sleep 5
15566         do_facet ost1 killall -TERM ofd_access_log_reader
15567         wait
15568         rc=$?
15569
15570         if ((rc != 0)); then
15571                 error "ofd_access_log_reader exited with rc = '${rc}'"
15572         fi
15573
15574         oalr_expect_event_count alr_log_entry "${trace}" 1
15575
15576         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15577         echo "entry = '${entry[*]}'" >&2
15578
15579         pfid2=${entry[4]}
15580         if [[ "${pfid1}" != "${pfid2}" ]]; then
15581                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15582         fi
15583
15584         size=${entry[8]}
15585         if ((size != 524288)); then
15586                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15587         fi
15588
15589         flags=${entry[10]}
15590         if [[ "${flags}" != "r" ]]; then
15591                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15592         fi
15593 }
15594 run_test 165b "ofd access log entries are produced and consumed"
15595
15596 test_165c() {
15597         local file="${DIR}/${tdir}/${tfile}"
15598         test_mkdir "${DIR}/${tdir}"
15599
15600         setup_165
15601
15602         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15603
15604         # 4096 / 64 = 64. Create twice as many entries.
15605         for ((i = 0; i < 128; i++)); do
15606                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15607         done
15608
15609         sync
15610         do_facet ost1 ofd_access_log_reader --list
15611         unlinkmany  "${file}-%d" 128
15612 }
15613 run_test 165c "full ofd access logs do not block IOs"
15614
15615 oal_peek_entry_count() {
15616         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15617 }
15618
15619 oal_expect_entry_count() {
15620         local entry_count=$(oal_peek_entry_count)
15621         local expect="$1"
15622
15623         if ((entry_count == expect)); then
15624                 return 0
15625         fi
15626
15627         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15628         do_facet ost1 ofd_access_log_reader --list >&2
15629         exit 1
15630 }
15631
15632 test_165d() {
15633         local trace="/tmp/${tfile}.trace"
15634         local file="${DIR}/${tdir}/${tfile}"
15635         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15636         local entry_count
15637         test_mkdir "${DIR}/${tdir}"
15638
15639         setup_165
15640         lfs setstripe -c 1 -i 0 "${file}"
15641
15642         do_facet ost1 lctl set_param "${param}=rw"
15643         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15644         oal_expect_entry_count 1
15645
15646         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15647         oal_expect_entry_count 2
15648
15649         do_facet ost1 lctl set_param "${param}=r"
15650         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15651         oal_expect_entry_count 2
15652
15653         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15654         oal_expect_entry_count 3
15655
15656         do_facet ost1 lctl set_param "${param}=w"
15657         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15658         oal_expect_entry_count 4
15659
15660         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15661         oal_expect_entry_count 4
15662
15663         do_facet ost1 lctl set_param "${param}=0"
15664         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15665         oal_expect_entry_count 4
15666
15667         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15668         oal_expect_entry_count 4
15669 }
15670 run_test 165d "ofd_access_log mask works"
15671
15672 test_169() {
15673         # do directio so as not to populate the page cache
15674         log "creating a 10 Mb file"
15675         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15676         log "starting reads"
15677         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15678         log "truncating the file"
15679         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15680         log "killing dd"
15681         kill %+ || true # reads might have finished
15682         echo "wait until dd is finished"
15683         wait
15684         log "removing the temporary file"
15685         rm -rf $DIR/$tfile || error "tmp file removal failed"
15686 }
15687 run_test 169 "parallel read and truncate should not deadlock"
15688
15689 test_170() {
15690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15691
15692         $LCTL clear     # bug 18514
15693         $LCTL debug_daemon start $TMP/${tfile}_log_good
15694         touch $DIR/$tfile
15695         $LCTL debug_daemon stop
15696         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15697                 error "sed failed to read log_good"
15698
15699         $LCTL debug_daemon start $TMP/${tfile}_log_good
15700         rm -rf $DIR/$tfile
15701         $LCTL debug_daemon stop
15702
15703         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15704                error "lctl df log_bad failed"
15705
15706         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15707         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15708
15709         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15710         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15711
15712         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15713                 error "bad_line good_line1 good_line2 are empty"
15714
15715         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15716         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15717         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15718
15719         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15720         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15721         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15722
15723         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15724                 error "bad_line_new good_line_new are empty"
15725
15726         local expected_good=$((good_line1 + good_line2*2))
15727
15728         rm -f $TMP/${tfile}*
15729         # LU-231, short malformed line may not be counted into bad lines
15730         if [ $bad_line -ne $bad_line_new ] &&
15731                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15732                 error "expected $bad_line bad lines, but got $bad_line_new"
15733                 return 1
15734         fi
15735
15736         if [ $expected_good -ne $good_line_new ]; then
15737                 error "expected $expected_good good lines, but got $good_line_new"
15738                 return 2
15739         fi
15740         true
15741 }
15742 run_test 170 "test lctl df to handle corrupted log ====================="
15743
15744 test_171() { # bug20592
15745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15746
15747         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15748         $LCTL set_param fail_loc=0x50e
15749         $LCTL set_param fail_val=3000
15750         multiop_bg_pause $DIR/$tfile O_s || true
15751         local MULTIPID=$!
15752         kill -USR1 $MULTIPID
15753         # cause log dump
15754         sleep 3
15755         wait $MULTIPID
15756         if dmesg | grep "recursive fault"; then
15757                 error "caught a recursive fault"
15758         fi
15759         $LCTL set_param fail_loc=0
15760         true
15761 }
15762 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15763
15764 # it would be good to share it with obdfilter-survey/iokit-libecho code
15765 setup_obdecho_osc () {
15766         local rc=0
15767         local ost_nid=$1
15768         local obdfilter_name=$2
15769         echo "Creating new osc for $obdfilter_name on $ost_nid"
15770         # make sure we can find loopback nid
15771         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15772
15773         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15774                            ${obdfilter_name}_osc_UUID || rc=2; }
15775         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15776                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15777         return $rc
15778 }
15779
15780 cleanup_obdecho_osc () {
15781         local obdfilter_name=$1
15782         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15783         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15784         return 0
15785 }
15786
15787 obdecho_test() {
15788         local OBD=$1
15789         local node=$2
15790         local pages=${3:-64}
15791         local rc=0
15792         local id
15793
15794         local count=10
15795         local obd_size=$(get_obd_size $node $OBD)
15796         local page_size=$(get_page_size $node)
15797         if [[ -n "$obd_size" ]]; then
15798                 local new_count=$((obd_size / (pages * page_size / 1024)))
15799                 [[ $new_count -ge $count ]] || count=$new_count
15800         fi
15801
15802         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15803         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15804                            rc=2; }
15805         if [ $rc -eq 0 ]; then
15806             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15807             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15808         fi
15809         echo "New object id is $id"
15810         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15811                            rc=4; }
15812         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15813                            "test_brw $count w v $pages $id" || rc=4; }
15814         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15815                            rc=4; }
15816         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15817                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15818         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15819                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15820         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15821         return $rc
15822 }
15823
15824 test_180a() {
15825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15826
15827         if ! [ -d /sys/fs/lustre/echo_client ] &&
15828            ! module_loaded obdecho; then
15829                 load_module obdecho/obdecho &&
15830                         stack_trap "rmmod obdecho" EXIT ||
15831                         error "unable to load obdecho on client"
15832         fi
15833
15834         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15835         local host=$($LCTL get_param -n osc.$osc.import |
15836                      awk '/current_connection:/ { print $2 }' )
15837         local target=$($LCTL get_param -n osc.$osc.import |
15838                        awk '/target:/ { print $2 }' )
15839         target=${target%_UUID}
15840
15841         if [ -n "$target" ]; then
15842                 setup_obdecho_osc $host $target &&
15843                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15844                         { error "obdecho setup failed with $?"; return; }
15845
15846                 obdecho_test ${target}_osc client ||
15847                         error "obdecho_test failed on ${target}_osc"
15848         else
15849                 $LCTL get_param osc.$osc.import
15850                 error "there is no osc.$osc.import target"
15851         fi
15852 }
15853 run_test 180a "test obdecho on osc"
15854
15855 test_180b() {
15856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15857         remote_ost_nodsh && skip "remote OST with nodsh"
15858
15859         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15860                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15861                 error "failed to load module obdecho"
15862
15863         local target=$(do_facet ost1 $LCTL dl |
15864                        awk '/obdfilter/ { print $4; exit; }')
15865
15866         if [ -n "$target" ]; then
15867                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15868         else
15869                 do_facet ost1 $LCTL dl
15870                 error "there is no obdfilter target on ost1"
15871         fi
15872 }
15873 run_test 180b "test obdecho directly on obdfilter"
15874
15875 test_180c() { # LU-2598
15876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15877         remote_ost_nodsh && skip "remote OST with nodsh"
15878         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15879                 skip "Need MDS version at least 2.4.0"
15880
15881         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15882                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15883                 error "failed to load module obdecho"
15884
15885         local target=$(do_facet ost1 $LCTL dl |
15886                        awk '/obdfilter/ { print $4; exit; }')
15887
15888         if [ -n "$target" ]; then
15889                 local pages=16384 # 64MB bulk I/O RPC size
15890
15891                 obdecho_test "$target" ost1 "$pages" ||
15892                         error "obdecho_test with pages=$pages failed with $?"
15893         else
15894                 do_facet ost1 $LCTL dl
15895                 error "there is no obdfilter target on ost1"
15896         fi
15897 }
15898 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15899
15900 test_181() { # bug 22177
15901         test_mkdir $DIR/$tdir
15902         # create enough files to index the directory
15903         createmany -o $DIR/$tdir/foobar 4000
15904         # print attributes for debug purpose
15905         lsattr -d .
15906         # open dir
15907         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15908         MULTIPID=$!
15909         # remove the files & current working dir
15910         unlinkmany $DIR/$tdir/foobar 4000
15911         rmdir $DIR/$tdir
15912         kill -USR1 $MULTIPID
15913         wait $MULTIPID
15914         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15915         return 0
15916 }
15917 run_test 181 "Test open-unlinked dir ========================"
15918
15919 test_182() {
15920         local fcount=1000
15921         local tcount=10
15922
15923         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15924
15925         $LCTL set_param mdc.*.rpc_stats=clear
15926
15927         for (( i = 0; i < $tcount; i++ )) ; do
15928                 mkdir $DIR/$tdir/$i
15929         done
15930
15931         for (( i = 0; i < $tcount; i++ )) ; do
15932                 createmany -o $DIR/$tdir/$i/f- $fcount &
15933         done
15934         wait
15935
15936         for (( i = 0; i < $tcount; i++ )) ; do
15937                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15938         done
15939         wait
15940
15941         $LCTL get_param mdc.*.rpc_stats
15942
15943         rm -rf $DIR/$tdir
15944 }
15945 run_test 182 "Test parallel modify metadata operations ================"
15946
15947 test_183() { # LU-2275
15948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15949         remote_mds_nodsh && skip "remote MDS with nodsh"
15950         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15951                 skip "Need MDS version at least 2.3.56"
15952
15953         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15954         echo aaa > $DIR/$tdir/$tfile
15955
15956 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15957         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15958
15959         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15960         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15961
15962         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15963
15964         # Flush negative dentry cache
15965         touch $DIR/$tdir/$tfile
15966
15967         # We are not checking for any leaked references here, they'll
15968         # become evident next time we do cleanup with module unload.
15969         rm -rf $DIR/$tdir
15970 }
15971 run_test 183 "No crash or request leak in case of strange dispositions ========"
15972
15973 # test suite 184 is for LU-2016, LU-2017
15974 test_184a() {
15975         check_swap_layouts_support
15976
15977         dir0=$DIR/$tdir/$testnum
15978         test_mkdir -p -c1 $dir0
15979         ref1=/etc/passwd
15980         ref2=/etc/group
15981         file1=$dir0/f1
15982         file2=$dir0/f2
15983         $LFS setstripe -c1 $file1
15984         cp $ref1 $file1
15985         $LFS setstripe -c2 $file2
15986         cp $ref2 $file2
15987         gen1=$($LFS getstripe -g $file1)
15988         gen2=$($LFS getstripe -g $file2)
15989
15990         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15991         gen=$($LFS getstripe -g $file1)
15992         [[ $gen1 != $gen ]] ||
15993                 "Layout generation on $file1 does not change"
15994         gen=$($LFS getstripe -g $file2)
15995         [[ $gen2 != $gen ]] ||
15996                 "Layout generation on $file2 does not change"
15997
15998         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15999         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16000
16001         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16002 }
16003 run_test 184a "Basic layout swap"
16004
16005 test_184b() {
16006         check_swap_layouts_support
16007
16008         dir0=$DIR/$tdir/$testnum
16009         mkdir -p $dir0 || error "creating dir $dir0"
16010         file1=$dir0/f1
16011         file2=$dir0/f2
16012         file3=$dir0/f3
16013         dir1=$dir0/d1
16014         dir2=$dir0/d2
16015         mkdir $dir1 $dir2
16016         $LFS setstripe -c1 $file1
16017         $LFS setstripe -c2 $file2
16018         $LFS setstripe -c1 $file3
16019         chown $RUNAS_ID $file3
16020         gen1=$($LFS getstripe -g $file1)
16021         gen2=$($LFS getstripe -g $file2)
16022
16023         $LFS swap_layouts $dir1 $dir2 &&
16024                 error "swap of directories layouts should fail"
16025         $LFS swap_layouts $dir1 $file1 &&
16026                 error "swap of directory and file layouts should fail"
16027         $RUNAS $LFS swap_layouts $file1 $file2 &&
16028                 error "swap of file we cannot write should fail"
16029         $LFS swap_layouts $file1 $file3 &&
16030                 error "swap of file with different owner should fail"
16031         /bin/true # to clear error code
16032 }
16033 run_test 184b "Forbidden layout swap (will generate errors)"
16034
16035 test_184c() {
16036         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16037         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16038         check_swap_layouts_support
16039         check_swap_layout_no_dom $DIR
16040
16041         local dir0=$DIR/$tdir/$testnum
16042         mkdir -p $dir0 || error "creating dir $dir0"
16043
16044         local ref1=$dir0/ref1
16045         local ref2=$dir0/ref2
16046         local file1=$dir0/file1
16047         local file2=$dir0/file2
16048         # create a file large enough for the concurrent test
16049         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16050         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16051         echo "ref file size: ref1($(stat -c %s $ref1))," \
16052              "ref2($(stat -c %s $ref2))"
16053
16054         cp $ref2 $file2
16055         dd if=$ref1 of=$file1 bs=16k &
16056         local DD_PID=$!
16057
16058         # Make sure dd starts to copy file, but wait at most 5 seconds
16059         local loops=0
16060         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16061
16062         $LFS swap_layouts $file1 $file2
16063         local rc=$?
16064         wait $DD_PID
16065         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16066         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16067
16068         # how many bytes copied before swapping layout
16069         local copied=$(stat -c %s $file2)
16070         local remaining=$(stat -c %s $ref1)
16071         remaining=$((remaining - copied))
16072         echo "Copied $copied bytes before swapping layout..."
16073
16074         cmp -n $copied $file1 $ref2 | grep differ &&
16075                 error "Content mismatch [0, $copied) of ref2 and file1"
16076         cmp -n $copied $file2 $ref1 ||
16077                 error "Content mismatch [0, $copied) of ref1 and file2"
16078         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16079                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16080
16081         # clean up
16082         rm -f $ref1 $ref2 $file1 $file2
16083 }
16084 run_test 184c "Concurrent write and layout swap"
16085
16086 test_184d() {
16087         check_swap_layouts_support
16088         check_swap_layout_no_dom $DIR
16089         [ -z "$(which getfattr 2>/dev/null)" ] &&
16090                 skip_env "no getfattr command"
16091
16092         local file1=$DIR/$tdir/$tfile-1
16093         local file2=$DIR/$tdir/$tfile-2
16094         local file3=$DIR/$tdir/$tfile-3
16095         local lovea1
16096         local lovea2
16097
16098         mkdir -p $DIR/$tdir
16099         touch $file1 || error "create $file1 failed"
16100         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16101                 error "create $file2 failed"
16102         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16103                 error "create $file3 failed"
16104         lovea1=$(get_layout_param $file1)
16105
16106         $LFS swap_layouts $file2 $file3 ||
16107                 error "swap $file2 $file3 layouts failed"
16108         $LFS swap_layouts $file1 $file2 ||
16109                 error "swap $file1 $file2 layouts failed"
16110
16111         lovea2=$(get_layout_param $file2)
16112         echo "$lovea1"
16113         echo "$lovea2"
16114         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16115
16116         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16117         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16118 }
16119 run_test 184d "allow stripeless layouts swap"
16120
16121 test_184e() {
16122         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16123                 skip "Need MDS version at least 2.6.94"
16124         check_swap_layouts_support
16125         check_swap_layout_no_dom $DIR
16126         [ -z "$(which getfattr 2>/dev/null)" ] &&
16127                 skip_env "no getfattr command"
16128
16129         local file1=$DIR/$tdir/$tfile-1
16130         local file2=$DIR/$tdir/$tfile-2
16131         local file3=$DIR/$tdir/$tfile-3
16132         local lovea
16133
16134         mkdir -p $DIR/$tdir
16135         touch $file1 || error "create $file1 failed"
16136         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16137                 error "create $file2 failed"
16138         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16139                 error "create $file3 failed"
16140
16141         $LFS swap_layouts $file1 $file2 ||
16142                 error "swap $file1 $file2 layouts failed"
16143
16144         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16145         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16146
16147         echo 123 > $file1 || error "Should be able to write into $file1"
16148
16149         $LFS swap_layouts $file1 $file3 ||
16150                 error "swap $file1 $file3 layouts failed"
16151
16152         echo 123 > $file1 || error "Should be able to write into $file1"
16153
16154         rm -rf $file1 $file2 $file3
16155 }
16156 run_test 184e "Recreate layout after stripeless layout swaps"
16157
16158 test_184f() {
16159         # Create a file with name longer than sizeof(struct stat) ==
16160         # 144 to see if we can get chars from the file name to appear
16161         # in the returned striping. Note that 'f' == 0x66.
16162         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16163
16164         mkdir -p $DIR/$tdir
16165         mcreate $DIR/$tdir/$file
16166         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16167                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16168         fi
16169 }
16170 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16171
16172 test_185() { # LU-2441
16173         # LU-3553 - no volatile file support in old servers
16174         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16175                 skip "Need MDS version at least 2.3.60"
16176
16177         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16178         touch $DIR/$tdir/spoo
16179         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16180         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16181                 error "cannot create/write a volatile file"
16182         [ "$FILESET" == "" ] &&
16183         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16184                 error "FID is still valid after close"
16185
16186         multiop_bg_pause $DIR/$tdir vVw4096_c
16187         local multi_pid=$!
16188
16189         local OLD_IFS=$IFS
16190         IFS=":"
16191         local fidv=($fid)
16192         IFS=$OLD_IFS
16193         # assume that the next FID for this client is sequential, since stdout
16194         # is unfortunately eaten by multiop_bg_pause
16195         local n=$((${fidv[1]} + 1))
16196         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16197         if [ "$FILESET" == "" ]; then
16198                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16199                         error "FID is missing before close"
16200         fi
16201         kill -USR1 $multi_pid
16202         # 1 second delay, so if mtime change we will see it
16203         sleep 1
16204         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16205         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16206 }
16207 run_test 185 "Volatile file support"
16208
16209 function create_check_volatile() {
16210         local idx=$1
16211         local tgt
16212
16213         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16214         local PID=$!
16215         sleep 1
16216         local FID=$(cat /tmp/${tfile}.fid)
16217         [ "$FID" == "" ] && error "can't get FID for volatile"
16218         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16219         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16220         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16221         kill -USR1 $PID
16222         wait
16223         sleep 1
16224         cancel_lru_locks mdc # flush opencache
16225         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16226         return 0
16227 }
16228
16229 test_185a(){
16230         # LU-12516 - volatile creation via .lustre
16231         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16232                 skip "Need MDS version at least 2.3.55"
16233
16234         create_check_volatile 0
16235         [ $MDSCOUNT -lt 2 ] && return 0
16236
16237         # DNE case
16238         create_check_volatile 1
16239
16240         return 0
16241 }
16242 run_test 185a "Volatile file creation in .lustre/fid/"
16243
16244 test_187a() {
16245         remote_mds_nodsh && skip "remote MDS with nodsh"
16246         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16247                 skip "Need MDS version at least 2.3.0"
16248
16249         local dir0=$DIR/$tdir/$testnum
16250         mkdir -p $dir0 || error "creating dir $dir0"
16251
16252         local file=$dir0/file1
16253         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16254         local dv1=$($LFS data_version $file)
16255         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16256         local dv2=$($LFS data_version $file)
16257         [[ $dv1 != $dv2 ]] ||
16258                 error "data version did not change on write $dv1 == $dv2"
16259
16260         # clean up
16261         rm -f $file1
16262 }
16263 run_test 187a "Test data version change"
16264
16265 test_187b() {
16266         remote_mds_nodsh && skip "remote MDS with nodsh"
16267         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16268                 skip "Need MDS version at least 2.3.0"
16269
16270         local dir0=$DIR/$tdir/$testnum
16271         mkdir -p $dir0 || error "creating dir $dir0"
16272
16273         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16274         [[ ${DV[0]} != ${DV[1]} ]] ||
16275                 error "data version did not change on write"\
16276                       " ${DV[0]} == ${DV[1]}"
16277
16278         # clean up
16279         rm -f $file1
16280 }
16281 run_test 187b "Test data version change on volatile file"
16282
16283 test_200() {
16284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16285         remote_mgs_nodsh && skip "remote MGS with nodsh"
16286         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16287
16288         local POOL=${POOL:-cea1}
16289         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16290         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16291         # Pool OST targets
16292         local first_ost=0
16293         local last_ost=$(($OSTCOUNT - 1))
16294         local ost_step=2
16295         local ost_list=$(seq $first_ost $ost_step $last_ost)
16296         local ost_range="$first_ost $last_ost $ost_step"
16297         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16298         local file_dir=$POOL_ROOT/file_tst
16299         local subdir=$test_path/subdir
16300         local rc=0
16301
16302         while : ; do
16303                 # former test_200a test_200b
16304                 pool_add $POOL                          || { rc=$? ; break; }
16305                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16306                 # former test_200c test_200d
16307                 mkdir -p $test_path
16308                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16309                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16310                 mkdir -p $subdir
16311                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16312                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16313                                                         || { rc=$? ; break; }
16314                 # former test_200e test_200f
16315                 local files=$((OSTCOUNT*3))
16316                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16317                                                         || { rc=$? ; break; }
16318                 pool_create_files $POOL $file_dir $files "$ost_list" \
16319                                                         || { rc=$? ; break; }
16320                 # former test_200g test_200h
16321                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16322                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16323
16324                 # former test_201a test_201b test_201c
16325                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16326
16327                 local f=$test_path/$tfile
16328                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16329                 pool_remove $POOL $f                    || { rc=$? ; break; }
16330                 break
16331         done
16332
16333         destroy_test_pools
16334
16335         return $rc
16336 }
16337 run_test 200 "OST pools"
16338
16339 # usage: default_attr <count | size | offset>
16340 default_attr() {
16341         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16342 }
16343
16344 # usage: check_default_stripe_attr
16345 check_default_stripe_attr() {
16346         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16347         case $1 in
16348         --stripe-count|-c)
16349                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16350         --stripe-size|-S)
16351                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16352         --stripe-index|-i)
16353                 EXPECTED=-1;;
16354         *)
16355                 error "unknown getstripe attr '$1'"
16356         esac
16357
16358         [ $ACTUAL == $EXPECTED ] ||
16359                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16360 }
16361
16362 test_204a() {
16363         test_mkdir $DIR/$tdir
16364         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16365
16366         check_default_stripe_attr --stripe-count
16367         check_default_stripe_attr --stripe-size
16368         check_default_stripe_attr --stripe-index
16369 }
16370 run_test 204a "Print default stripe attributes"
16371
16372 test_204b() {
16373         test_mkdir $DIR/$tdir
16374         $LFS setstripe --stripe-count 1 $DIR/$tdir
16375
16376         check_default_stripe_attr --stripe-size
16377         check_default_stripe_attr --stripe-index
16378 }
16379 run_test 204b "Print default stripe size and offset"
16380
16381 test_204c() {
16382         test_mkdir $DIR/$tdir
16383         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16384
16385         check_default_stripe_attr --stripe-count
16386         check_default_stripe_attr --stripe-index
16387 }
16388 run_test 204c "Print default stripe count and offset"
16389
16390 test_204d() {
16391         test_mkdir $DIR/$tdir
16392         $LFS setstripe --stripe-index 0 $DIR/$tdir
16393
16394         check_default_stripe_attr --stripe-count
16395         check_default_stripe_attr --stripe-size
16396 }
16397 run_test 204d "Print default stripe count and size"
16398
16399 test_204e() {
16400         test_mkdir $DIR/$tdir
16401         $LFS setstripe -d $DIR/$tdir
16402
16403         check_default_stripe_attr --stripe-count --raw
16404         check_default_stripe_attr --stripe-size --raw
16405         check_default_stripe_attr --stripe-index --raw
16406 }
16407 run_test 204e "Print raw stripe attributes"
16408
16409 test_204f() {
16410         test_mkdir $DIR/$tdir
16411         $LFS setstripe --stripe-count 1 $DIR/$tdir
16412
16413         check_default_stripe_attr --stripe-size --raw
16414         check_default_stripe_attr --stripe-index --raw
16415 }
16416 run_test 204f "Print raw stripe size and offset"
16417
16418 test_204g() {
16419         test_mkdir $DIR/$tdir
16420         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16421
16422         check_default_stripe_attr --stripe-count --raw
16423         check_default_stripe_attr --stripe-index --raw
16424 }
16425 run_test 204g "Print raw stripe count and offset"
16426
16427 test_204h() {
16428         test_mkdir $DIR/$tdir
16429         $LFS setstripe --stripe-index 0 $DIR/$tdir
16430
16431         check_default_stripe_attr --stripe-count --raw
16432         check_default_stripe_attr --stripe-size --raw
16433 }
16434 run_test 204h "Print raw stripe count and size"
16435
16436 # Figure out which job scheduler is being used, if any,
16437 # or use a fake one
16438 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16439         JOBENV=SLURM_JOB_ID
16440 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16441         JOBENV=LSB_JOBID
16442 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16443         JOBENV=PBS_JOBID
16444 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16445         JOBENV=LOADL_STEP_ID
16446 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16447         JOBENV=JOB_ID
16448 else
16449         $LCTL list_param jobid_name > /dev/null 2>&1
16450         if [ $? -eq 0 ]; then
16451                 JOBENV=nodelocal
16452         else
16453                 JOBENV=FAKE_JOBID
16454         fi
16455 fi
16456 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16457
16458 verify_jobstats() {
16459         local cmd=($1)
16460         shift
16461         local facets="$@"
16462
16463 # we don't really need to clear the stats for this test to work, since each
16464 # command has a unique jobid, but it makes debugging easier if needed.
16465 #       for facet in $facets; do
16466 #               local dev=$(convert_facet2label $facet)
16467 #               # clear old jobstats
16468 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16469 #       done
16470
16471         # use a new JobID for each test, or we might see an old one
16472         [ "$JOBENV" = "FAKE_JOBID" ] &&
16473                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16474
16475         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16476
16477         [ "$JOBENV" = "nodelocal" ] && {
16478                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16479                 $LCTL set_param jobid_name=$FAKE_JOBID
16480                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16481         }
16482
16483         log "Test: ${cmd[*]}"
16484         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16485
16486         if [ $JOBENV = "FAKE_JOBID" ]; then
16487                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16488         else
16489                 ${cmd[*]}
16490         fi
16491
16492         # all files are created on OST0000
16493         for facet in $facets; do
16494                 local stats="*.$(convert_facet2label $facet).job_stats"
16495
16496                 # strip out libtool wrappers for in-tree executables
16497                 if [ $(do_facet $facet lctl get_param $stats |
16498                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16499                         do_facet $facet lctl get_param $stats
16500                         error "No jobstats for $JOBVAL found on $facet::$stats"
16501                 fi
16502         done
16503 }
16504
16505 jobstats_set() {
16506         local new_jobenv=$1
16507
16508         set_persistent_param_and_check client "jobid_var" \
16509                 "$FSNAME.sys.jobid_var" $new_jobenv
16510 }
16511
16512 test_205a() { # Job stats
16513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16514         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16515                 skip "Need MDS version with at least 2.7.1"
16516         remote_mgs_nodsh && skip "remote MGS with nodsh"
16517         remote_mds_nodsh && skip "remote MDS with nodsh"
16518         remote_ost_nodsh && skip "remote OST with nodsh"
16519         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16520                 skip "Server doesn't support jobstats"
16521         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16522
16523         local old_jobenv=$($LCTL get_param -n jobid_var)
16524         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16525
16526         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16527                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16528         else
16529                 stack_trap "do_facet mgs $PERM_CMD \
16530                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16531         fi
16532         changelog_register
16533
16534         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16535                                 mdt.*.job_cleanup_interval | head -n 1)
16536         local new_interval=5
16537         do_facet $SINGLEMDS \
16538                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16539         stack_trap "do_facet $SINGLEMDS \
16540                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16541         local start=$SECONDS
16542
16543         local cmd
16544         # mkdir
16545         cmd="mkdir $DIR/$tdir"
16546         verify_jobstats "$cmd" "$SINGLEMDS"
16547         # rmdir
16548         cmd="rmdir $DIR/$tdir"
16549         verify_jobstats "$cmd" "$SINGLEMDS"
16550         # mkdir on secondary MDT
16551         if [ $MDSCOUNT -gt 1 ]; then
16552                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16553                 verify_jobstats "$cmd" "mds2"
16554         fi
16555         # mknod
16556         cmd="mknod $DIR/$tfile c 1 3"
16557         verify_jobstats "$cmd" "$SINGLEMDS"
16558         # unlink
16559         cmd="rm -f $DIR/$tfile"
16560         verify_jobstats "$cmd" "$SINGLEMDS"
16561         # create all files on OST0000 so verify_jobstats can find OST stats
16562         # open & close
16563         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16564         verify_jobstats "$cmd" "$SINGLEMDS"
16565         # setattr
16566         cmd="touch $DIR/$tfile"
16567         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16568         # write
16569         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16570         verify_jobstats "$cmd" "ost1"
16571         # read
16572         cancel_lru_locks osc
16573         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16574         verify_jobstats "$cmd" "ost1"
16575         # truncate
16576         cmd="$TRUNCATE $DIR/$tfile 0"
16577         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16578         # rename
16579         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16580         verify_jobstats "$cmd" "$SINGLEMDS"
16581         # jobstats expiry - sleep until old stats should be expired
16582         local left=$((new_interval + 5 - (SECONDS - start)))
16583         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16584                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16585                         "0" $left
16586         cmd="mkdir $DIR/$tdir.expire"
16587         verify_jobstats "$cmd" "$SINGLEMDS"
16588         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16589             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16590
16591         # Ensure that jobid are present in changelog (if supported by MDS)
16592         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16593                 changelog_dump | tail -10
16594                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16595                 [ $jobids -eq 9 ] ||
16596                         error "Wrong changelog jobid count $jobids != 9"
16597
16598                 # LU-5862
16599                 JOBENV="disable"
16600                 jobstats_set $JOBENV
16601                 touch $DIR/$tfile
16602                 changelog_dump | grep $tfile
16603                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16604                 [ $jobids -eq 0 ] ||
16605                         error "Unexpected jobids when jobid_var=$JOBENV"
16606         fi
16607
16608         # test '%j' access to environment variable - if supported
16609         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16610                 JOBENV="JOBCOMPLEX"
16611                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16612
16613                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16614         fi
16615
16616         # test '%j' access to per-session jobid - if supported
16617         if lctl list_param jobid_this_session > /dev/null 2>&1
16618         then
16619                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16620                 lctl set_param jobid_this_session=$USER
16621
16622                 JOBENV="JOBCOMPLEX"
16623                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16624
16625                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16626         fi
16627 }
16628 run_test 205a "Verify job stats"
16629
16630 # LU-13117, LU-13597
16631 test_205b() {
16632         job_stats="mdt.*.job_stats"
16633         $LCTL set_param $job_stats=clear
16634         # Setting jobid_var to USER might not be supported
16635         $LCTL set_param jobid_var=USER || true
16636         $LCTL set_param jobid_name="%e.%u"
16637         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16638         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16639                 grep "job_id:.*foolish" &&
16640                         error "Unexpected jobid found"
16641         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16642                 grep "open:.*min.*max.*sum" ||
16643                         error "wrong job_stats format found"
16644 }
16645 run_test 205b "Verify job stats jobid and output format"
16646
16647 # LU-13733
16648 test_205c() {
16649         $LCTL set_param llite.*.stats=0
16650         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16651         $LCTL get_param llite.*.stats
16652         $LCTL get_param llite.*.stats | grep \
16653                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16654                         error "wrong client stats format found"
16655 }
16656 run_test 205c "Verify client stats format"
16657
16658 # LU-1480, LU-1773 and LU-1657
16659 test_206() {
16660         mkdir -p $DIR/$tdir
16661         $LFS setstripe -c -1 $DIR/$tdir
16662 #define OBD_FAIL_LOV_INIT 0x1403
16663         $LCTL set_param fail_loc=0xa0001403
16664         $LCTL set_param fail_val=1
16665         touch $DIR/$tdir/$tfile || true
16666 }
16667 run_test 206 "fail lov_init_raid0() doesn't lbug"
16668
16669 test_207a() {
16670         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16671         local fsz=`stat -c %s $DIR/$tfile`
16672         cancel_lru_locks mdc
16673
16674         # do not return layout in getattr intent
16675 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16676         $LCTL set_param fail_loc=0x170
16677         local sz=`stat -c %s $DIR/$tfile`
16678
16679         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16680
16681         rm -rf $DIR/$tfile
16682 }
16683 run_test 207a "can refresh layout at glimpse"
16684
16685 test_207b() {
16686         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16687         local cksum=`md5sum $DIR/$tfile`
16688         local fsz=`stat -c %s $DIR/$tfile`
16689         cancel_lru_locks mdc
16690         cancel_lru_locks osc
16691
16692         # do not return layout in getattr intent
16693 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16694         $LCTL set_param fail_loc=0x171
16695
16696         # it will refresh layout after the file is opened but before read issues
16697         echo checksum is "$cksum"
16698         echo "$cksum" |md5sum -c --quiet || error "file differs"
16699
16700         rm -rf $DIR/$tfile
16701 }
16702 run_test 207b "can refresh layout at open"
16703
16704 test_208() {
16705         # FIXME: in this test suite, only RD lease is used. This is okay
16706         # for now as only exclusive open is supported. After generic lease
16707         # is done, this test suite should be revised. - Jinshan
16708
16709         remote_mds_nodsh && skip "remote MDS with nodsh"
16710         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16711                 skip "Need MDS version at least 2.4.52"
16712
16713         echo "==== test 1: verify get lease work"
16714         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16715
16716         echo "==== test 2: verify lease can be broken by upcoming open"
16717         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16718         local PID=$!
16719         sleep 1
16720
16721         $MULTIOP $DIR/$tfile oO_RDONLY:c
16722         kill -USR1 $PID && wait $PID || error "break lease error"
16723
16724         echo "==== test 3: verify lease can't be granted if an open already exists"
16725         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16726         local PID=$!
16727         sleep 1
16728
16729         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16730         kill -USR1 $PID && wait $PID || error "open file error"
16731
16732         echo "==== test 4: lease can sustain over recovery"
16733         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16734         PID=$!
16735         sleep 1
16736
16737         fail mds1
16738
16739         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16740
16741         echo "==== test 5: lease broken can't be regained by replay"
16742         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16743         PID=$!
16744         sleep 1
16745
16746         # open file to break lease and then recovery
16747         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16748         fail mds1
16749
16750         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16751
16752         rm -f $DIR/$tfile
16753 }
16754 run_test 208 "Exclusive open"
16755
16756 test_209() {
16757         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16758                 skip_env "must have disp_stripe"
16759
16760         touch $DIR/$tfile
16761         sync; sleep 5; sync;
16762
16763         echo 3 > /proc/sys/vm/drop_caches
16764         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16765                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16766         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16767
16768         # open/close 500 times
16769         for i in $(seq 500); do
16770                 cat $DIR/$tfile
16771         done
16772
16773         echo 3 > /proc/sys/vm/drop_caches
16774         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16775                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16776         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16777
16778         echo "before: $req_before, after: $req_after"
16779         [ $((req_after - req_before)) -ge 300 ] &&
16780                 error "open/close requests are not freed"
16781         return 0
16782 }
16783 run_test 209 "read-only open/close requests should be freed promptly"
16784
16785 test_210() {
16786         local pid
16787
16788         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16789         pid=$!
16790         sleep 1
16791
16792         $LFS getstripe $DIR/$tfile
16793         kill -USR1 $pid
16794         wait $pid || error "multiop failed"
16795
16796         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16797         pid=$!
16798         sleep 1
16799
16800         $LFS getstripe $DIR/$tfile
16801         kill -USR1 $pid
16802         wait $pid || error "multiop failed"
16803 }
16804 run_test 210 "lfs getstripe does not break leases"
16805
16806 test_212() {
16807         size=`date +%s`
16808         size=$((size % 8192 + 1))
16809         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16810         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16811         rm -f $DIR/f212 $DIR/f212.xyz
16812 }
16813 run_test 212 "Sendfile test ============================================"
16814
16815 test_213() {
16816         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16817         cancel_lru_locks osc
16818         lctl set_param fail_loc=0x8000040f
16819         # generate a read lock
16820         cat $DIR/$tfile > /dev/null
16821         # write to the file, it will try to cancel the above read lock.
16822         cat /etc/hosts >> $DIR/$tfile
16823 }
16824 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16825
16826 test_214() { # for bug 20133
16827         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16828         for (( i=0; i < 340; i++ )) ; do
16829                 touch $DIR/$tdir/d214c/a$i
16830         done
16831
16832         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16833         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16834         ls $DIR/d214c || error "ls $DIR/d214c failed"
16835         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16836         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16837 }
16838 run_test 214 "hash-indexed directory test - bug 20133"
16839
16840 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16841 create_lnet_proc_files() {
16842         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16843 }
16844
16845 # counterpart of create_lnet_proc_files
16846 remove_lnet_proc_files() {
16847         rm -f $TMP/lnet_$1.sys
16848 }
16849
16850 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16851 # 3rd arg as regexp for body
16852 check_lnet_proc_stats() {
16853         local l=$(cat "$TMP/lnet_$1" |wc -l)
16854         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16855
16856         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16857 }
16858
16859 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16860 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16861 # optional and can be regexp for 2nd line (lnet.routes case)
16862 check_lnet_proc_entry() {
16863         local blp=2          # blp stands for 'position of 1st line of body'
16864         [ -z "$5" ] || blp=3 # lnet.routes case
16865
16866         local l=$(cat "$TMP/lnet_$1" |wc -l)
16867         # subtracting one from $blp because the body can be empty
16868         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16869
16870         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16871                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16872
16873         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16874                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16875
16876         # bail out if any unexpected line happened
16877         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16878         [ "$?" != 0 ] || error "$2 misformatted"
16879 }
16880
16881 test_215() { # for bugs 18102, 21079, 21517
16882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16883
16884         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16885         local P='[1-9][0-9]*'           # positive numeric
16886         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16887         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16888         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16889         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16890
16891         local L1 # regexp for 1st line
16892         local L2 # regexp for 2nd line (optional)
16893         local BR # regexp for the rest (body)
16894
16895         # lnet.stats should look as 11 space-separated non-negative numerics
16896         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16897         create_lnet_proc_files "stats"
16898         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16899         remove_lnet_proc_files "stats"
16900
16901         # lnet.routes should look like this:
16902         # Routing disabled/enabled
16903         # net hops priority state router
16904         # where net is a string like tcp0, hops > 0, priority >= 0,
16905         # state is up/down,
16906         # router is a string like 192.168.1.1@tcp2
16907         L1="^Routing (disabled|enabled)$"
16908         L2="^net +hops +priority +state +router$"
16909         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16910         create_lnet_proc_files "routes"
16911         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16912         remove_lnet_proc_files "routes"
16913
16914         # lnet.routers should look like this:
16915         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16916         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16917         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16918         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16919         L1="^ref +rtr_ref +alive +router$"
16920         BR="^$P +$P +(up|down) +$NID$"
16921         create_lnet_proc_files "routers"
16922         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16923         remove_lnet_proc_files "routers"
16924
16925         # lnet.peers should look like this:
16926         # nid refs state last max rtr min tx min queue
16927         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16928         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16929         # numeric (0 or >0 or <0), queue >= 0.
16930         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16931         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16932         create_lnet_proc_files "peers"
16933         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16934         remove_lnet_proc_files "peers"
16935
16936         # lnet.buffers  should look like this:
16937         # pages count credits min
16938         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16939         L1="^pages +count +credits +min$"
16940         BR="^ +$N +$N +$I +$I$"
16941         create_lnet_proc_files "buffers"
16942         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16943         remove_lnet_proc_files "buffers"
16944
16945         # lnet.nis should look like this:
16946         # nid status alive refs peer rtr max tx min
16947         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16948         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16949         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16950         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16951         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16952         create_lnet_proc_files "nis"
16953         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16954         remove_lnet_proc_files "nis"
16955
16956         # can we successfully write to lnet.stats?
16957         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16958 }
16959 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16960
16961 test_216() { # bug 20317
16962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16963         remote_ost_nodsh && skip "remote OST with nodsh"
16964
16965         local node
16966         local facets=$(get_facets OST)
16967         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16968
16969         save_lustre_params client "osc.*.contention_seconds" > $p
16970         save_lustre_params $facets \
16971                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16972         save_lustre_params $facets \
16973                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16974         save_lustre_params $facets \
16975                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16976         clear_stats osc.*.osc_stats
16977
16978         # agressive lockless i/o settings
16979         do_nodes $(comma_list $(osts_nodes)) \
16980                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16981                         ldlm.namespaces.filter-*.contended_locks=0 \
16982                         ldlm.namespaces.filter-*.contention_seconds=60"
16983         lctl set_param -n osc.*.contention_seconds=60
16984
16985         $DIRECTIO write $DIR/$tfile 0 10 4096
16986         $CHECKSTAT -s 40960 $DIR/$tfile
16987
16988         # disable lockless i/o
16989         do_nodes $(comma_list $(osts_nodes)) \
16990                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16991                         ldlm.namespaces.filter-*.contended_locks=32 \
16992                         ldlm.namespaces.filter-*.contention_seconds=0"
16993         lctl set_param -n osc.*.contention_seconds=0
16994         clear_stats osc.*.osc_stats
16995
16996         dd if=/dev/zero of=$DIR/$tfile count=0
16997         $CHECKSTAT -s 0 $DIR/$tfile
16998
16999         restore_lustre_params <$p
17000         rm -f $p
17001         rm $DIR/$tfile
17002 }
17003 run_test 216 "check lockless direct write updates file size and kms correctly"
17004
17005 test_217() { # bug 22430
17006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17007
17008         local node
17009         local nid
17010
17011         for node in $(nodes_list); do
17012                 nid=$(host_nids_address $node $NETTYPE)
17013                 if [[ $nid = *-* ]] ; then
17014                         echo "lctl ping $(h2nettype $nid)"
17015                         lctl ping $(h2nettype $nid)
17016                 else
17017                         echo "skipping $node (no hyphen detected)"
17018                 fi
17019         done
17020 }
17021 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17022
17023 test_218() {
17024        # do directio so as not to populate the page cache
17025        log "creating a 10 Mb file"
17026        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17027        log "starting reads"
17028        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17029        log "truncating the file"
17030        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17031        log "killing dd"
17032        kill %+ || true # reads might have finished
17033        echo "wait until dd is finished"
17034        wait
17035        log "removing the temporary file"
17036        rm -rf $DIR/$tfile || error "tmp file removal failed"
17037 }
17038 run_test 218 "parallel read and truncate should not deadlock"
17039
17040 test_219() {
17041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17042
17043         # write one partial page
17044         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17045         # set no grant so vvp_io_commit_write will do sync write
17046         $LCTL set_param fail_loc=0x411
17047         # write a full page at the end of file
17048         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17049
17050         $LCTL set_param fail_loc=0
17051         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17052         $LCTL set_param fail_loc=0x411
17053         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17054
17055         # LU-4201
17056         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17057         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17058 }
17059 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17060
17061 test_220() { #LU-325
17062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17063         remote_ost_nodsh && skip "remote OST with nodsh"
17064         remote_mds_nodsh && skip "remote MDS with nodsh"
17065         remote_mgs_nodsh && skip "remote MGS with nodsh"
17066
17067         local OSTIDX=0
17068
17069         # create on MDT0000 so the last_id and next_id are correct
17070         mkdir $DIR/$tdir
17071         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17072         OST=${OST%_UUID}
17073
17074         # on the mdt's osc
17075         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17076         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17077                         osp.$mdtosc_proc1.prealloc_last_id)
17078         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17079                         osp.$mdtosc_proc1.prealloc_next_id)
17080
17081         $LFS df -i
17082
17083         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17084         #define OBD_FAIL_OST_ENOINO              0x229
17085         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17086         create_pool $FSNAME.$TESTNAME || return 1
17087         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17088
17089         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17090
17091         MDSOBJS=$((last_id - next_id))
17092         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17093
17094         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17095         echo "OST still has $count kbytes free"
17096
17097         echo "create $MDSOBJS files @next_id..."
17098         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17099
17100         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17101                         osp.$mdtosc_proc1.prealloc_last_id)
17102         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17103                         osp.$mdtosc_proc1.prealloc_next_id)
17104
17105         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17106         $LFS df -i
17107
17108         echo "cleanup..."
17109
17110         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17111         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17112
17113         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17114                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17115         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17116                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17117         echo "unlink $MDSOBJS files @$next_id..."
17118         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17119 }
17120 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17121
17122 test_221() {
17123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17124
17125         dd if=`which date` of=$MOUNT/date oflag=sync
17126         chmod +x $MOUNT/date
17127
17128         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17129         $LCTL set_param fail_loc=0x80001401
17130
17131         $MOUNT/date > /dev/null
17132         rm -f $MOUNT/date
17133 }
17134 run_test 221 "make sure fault and truncate race to not cause OOM"
17135
17136 test_222a () {
17137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17138
17139         rm -rf $DIR/$tdir
17140         test_mkdir $DIR/$tdir
17141         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17142         createmany -o $DIR/$tdir/$tfile 10
17143         cancel_lru_locks mdc
17144         cancel_lru_locks osc
17145         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17146         $LCTL set_param fail_loc=0x31a
17147         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17148         $LCTL set_param fail_loc=0
17149         rm -r $DIR/$tdir
17150 }
17151 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17152
17153 test_222b () {
17154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17155
17156         rm -rf $DIR/$tdir
17157         test_mkdir $DIR/$tdir
17158         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17159         createmany -o $DIR/$tdir/$tfile 10
17160         cancel_lru_locks mdc
17161         cancel_lru_locks osc
17162         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17163         $LCTL set_param fail_loc=0x31a
17164         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17165         $LCTL set_param fail_loc=0
17166 }
17167 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17168
17169 test_223 () {
17170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17171
17172         rm -rf $DIR/$tdir
17173         test_mkdir $DIR/$tdir
17174         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17175         createmany -o $DIR/$tdir/$tfile 10
17176         cancel_lru_locks mdc
17177         cancel_lru_locks osc
17178         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17179         $LCTL set_param fail_loc=0x31b
17180         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17181         $LCTL set_param fail_loc=0
17182         rm -r $DIR/$tdir
17183 }
17184 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17185
17186 test_224a() { # LU-1039, MRP-303
17187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17188
17189         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17190         $LCTL set_param fail_loc=0x508
17191         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17192         $LCTL set_param fail_loc=0
17193         df $DIR
17194 }
17195 run_test 224a "Don't panic on bulk IO failure"
17196
17197 test_224b() { # LU-1039, MRP-303
17198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17199
17200         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17201         cancel_lru_locks osc
17202         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17203         $LCTL set_param fail_loc=0x515
17204         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17205         $LCTL set_param fail_loc=0
17206         df $DIR
17207 }
17208 run_test 224b "Don't panic on bulk IO failure"
17209
17210 test_224c() { # LU-6441
17211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17212         remote_mds_nodsh && skip "remote MDS with nodsh"
17213
17214         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17215         save_writethrough $p
17216         set_cache writethrough on
17217
17218         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17219         local at_max=$($LCTL get_param -n at_max)
17220         local timeout=$($LCTL get_param -n timeout)
17221         local test_at="at_max"
17222         local param_at="$FSNAME.sys.at_max"
17223         local test_timeout="timeout"
17224         local param_timeout="$FSNAME.sys.timeout"
17225
17226         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17227
17228         set_persistent_param_and_check client "$test_at" "$param_at" 0
17229         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17230
17231         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17232         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17233         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17234         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17235         sync
17236         do_facet ost1 "$LCTL set_param fail_loc=0"
17237
17238         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17239         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17240                 $timeout
17241
17242         $LCTL set_param -n $pages_per_rpc
17243         restore_lustre_params < $p
17244         rm -f $p
17245 }
17246 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17247
17248 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17249 test_225a () {
17250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17251         if [ -z ${MDSSURVEY} ]; then
17252                 skip_env "mds-survey not found"
17253         fi
17254         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17255                 skip "Need MDS version at least 2.2.51"
17256
17257         local mds=$(facet_host $SINGLEMDS)
17258         local target=$(do_nodes $mds 'lctl dl' |
17259                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17260
17261         local cmd1="file_count=1000 thrhi=4"
17262         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17263         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17264         local cmd="$cmd1 $cmd2 $cmd3"
17265
17266         rm -f ${TMP}/mds_survey*
17267         echo + $cmd
17268         eval $cmd || error "mds-survey with zero-stripe failed"
17269         cat ${TMP}/mds_survey*
17270         rm -f ${TMP}/mds_survey*
17271 }
17272 run_test 225a "Metadata survey sanity with zero-stripe"
17273
17274 test_225b () {
17275         if [ -z ${MDSSURVEY} ]; then
17276                 skip_env "mds-survey not found"
17277         fi
17278         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17279                 skip "Need MDS version at least 2.2.51"
17280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17281         remote_mds_nodsh && skip "remote MDS with nodsh"
17282         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17283                 skip_env "Need to mount OST to test"
17284         fi
17285
17286         local mds=$(facet_host $SINGLEMDS)
17287         local target=$(do_nodes $mds 'lctl dl' |
17288                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17289
17290         local cmd1="file_count=1000 thrhi=4"
17291         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17292         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17293         local cmd="$cmd1 $cmd2 $cmd3"
17294
17295         rm -f ${TMP}/mds_survey*
17296         echo + $cmd
17297         eval $cmd || error "mds-survey with stripe_count failed"
17298         cat ${TMP}/mds_survey*
17299         rm -f ${TMP}/mds_survey*
17300 }
17301 run_test 225b "Metadata survey sanity with stripe_count = 1"
17302
17303 mcreate_path2fid () {
17304         local mode=$1
17305         local major=$2
17306         local minor=$3
17307         local name=$4
17308         local desc=$5
17309         local path=$DIR/$tdir/$name
17310         local fid
17311         local rc
17312         local fid_path
17313
17314         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17315                 error "cannot create $desc"
17316
17317         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17318         rc=$?
17319         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17320
17321         fid_path=$($LFS fid2path $MOUNT $fid)
17322         rc=$?
17323         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17324
17325         [ "$path" == "$fid_path" ] ||
17326                 error "fid2path returned $fid_path, expected $path"
17327
17328         echo "pass with $path and $fid"
17329 }
17330
17331 test_226a () {
17332         rm -rf $DIR/$tdir
17333         mkdir -p $DIR/$tdir
17334
17335         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17336         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17337         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17338         mcreate_path2fid 0040666 0 0 dir "directory"
17339         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17340         mcreate_path2fid 0100666 0 0 file "regular file"
17341         mcreate_path2fid 0120666 0 0 link "symbolic link"
17342         mcreate_path2fid 0140666 0 0 sock "socket"
17343 }
17344 run_test 226a "call path2fid and fid2path on files of all type"
17345
17346 test_226b () {
17347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17348
17349         local MDTIDX=1
17350
17351         rm -rf $DIR/$tdir
17352         mkdir -p $DIR/$tdir
17353         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17354                 error "create remote directory failed"
17355         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17356         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17357                                 "character special file (null)"
17358         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17359                                 "character special file (no device)"
17360         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17361         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17362                                 "block special file (loop)"
17363         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17364         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17365         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17366 }
17367 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17368
17369 test_226c () {
17370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17371         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17372                 skip "Need MDS version at least 2.13.55"
17373
17374         local submnt=/mnt/submnt
17375         local srcfile=/etc/passwd
17376         local dstfile=$submnt/passwd
17377         local path
17378         local fid
17379
17380         rm -rf $DIR/$tdir
17381         rm -rf $submnt
17382         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17383                 error "create remote directory failed"
17384         mkdir -p $submnt || error "create $submnt failed"
17385         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17386                 error "mount $submnt failed"
17387         stack_trap "umount $submnt" EXIT
17388
17389         cp $srcfile $dstfile
17390         fid=$($LFS path2fid $dstfile)
17391         path=$($LFS fid2path $submnt "$fid")
17392         [ "$path" = "$dstfile" ] ||
17393                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17394 }
17395 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17396
17397 # LU-1299 Executing or running ldd on a truncated executable does not
17398 # cause an out-of-memory condition.
17399 test_227() {
17400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17401         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17402
17403         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17404         chmod +x $MOUNT/date
17405
17406         $MOUNT/date > /dev/null
17407         ldd $MOUNT/date > /dev/null
17408         rm -f $MOUNT/date
17409 }
17410 run_test 227 "running truncated executable does not cause OOM"
17411
17412 # LU-1512 try to reuse idle OI blocks
17413 test_228a() {
17414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17415         remote_mds_nodsh && skip "remote MDS with nodsh"
17416         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17417
17418         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17419         local myDIR=$DIR/$tdir
17420
17421         mkdir -p $myDIR
17422         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17423         $LCTL set_param fail_loc=0x80001002
17424         createmany -o $myDIR/t- 10000
17425         $LCTL set_param fail_loc=0
17426         # The guard is current the largest FID holder
17427         touch $myDIR/guard
17428         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17429                     tr -d '[')
17430         local IDX=$(($SEQ % 64))
17431
17432         do_facet $SINGLEMDS sync
17433         # Make sure journal flushed.
17434         sleep 6
17435         local blk1=$(do_facet $SINGLEMDS \
17436                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17437                      grep Blockcount | awk '{print $4}')
17438
17439         # Remove old files, some OI blocks will become idle.
17440         unlinkmany $myDIR/t- 10000
17441         # Create new files, idle OI blocks should be reused.
17442         createmany -o $myDIR/t- 2000
17443         do_facet $SINGLEMDS sync
17444         # Make sure journal flushed.
17445         sleep 6
17446         local blk2=$(do_facet $SINGLEMDS \
17447                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17448                      grep Blockcount | awk '{print $4}')
17449
17450         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17451 }
17452 run_test 228a "try to reuse idle OI blocks"
17453
17454 test_228b() {
17455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17456         remote_mds_nodsh && skip "remote MDS with nodsh"
17457         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17458
17459         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17460         local myDIR=$DIR/$tdir
17461
17462         mkdir -p $myDIR
17463         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17464         $LCTL set_param fail_loc=0x80001002
17465         createmany -o $myDIR/t- 10000
17466         $LCTL set_param fail_loc=0
17467         # The guard is current the largest FID holder
17468         touch $myDIR/guard
17469         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17470                     tr -d '[')
17471         local IDX=$(($SEQ % 64))
17472
17473         do_facet $SINGLEMDS sync
17474         # Make sure journal flushed.
17475         sleep 6
17476         local blk1=$(do_facet $SINGLEMDS \
17477                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17478                      grep Blockcount | awk '{print $4}')
17479
17480         # Remove old files, some OI blocks will become idle.
17481         unlinkmany $myDIR/t- 10000
17482
17483         # stop the MDT
17484         stop $SINGLEMDS || error "Fail to stop MDT."
17485         # remount the MDT
17486         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17487
17488         df $MOUNT || error "Fail to df."
17489         # Create new files, idle OI blocks should be reused.
17490         createmany -o $myDIR/t- 2000
17491         do_facet $SINGLEMDS sync
17492         # Make sure journal flushed.
17493         sleep 6
17494         local blk2=$(do_facet $SINGLEMDS \
17495                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17496                      grep Blockcount | awk '{print $4}')
17497
17498         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17499 }
17500 run_test 228b "idle OI blocks can be reused after MDT restart"
17501
17502 #LU-1881
17503 test_228c() {
17504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17505         remote_mds_nodsh && skip "remote MDS with nodsh"
17506         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17507
17508         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17509         local myDIR=$DIR/$tdir
17510
17511         mkdir -p $myDIR
17512         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17513         $LCTL set_param fail_loc=0x80001002
17514         # 20000 files can guarantee there are index nodes in the OI file
17515         createmany -o $myDIR/t- 20000
17516         $LCTL set_param fail_loc=0
17517         # The guard is current the largest FID holder
17518         touch $myDIR/guard
17519         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17520                     tr -d '[')
17521         local IDX=$(($SEQ % 64))
17522
17523         do_facet $SINGLEMDS sync
17524         # Make sure journal flushed.
17525         sleep 6
17526         local blk1=$(do_facet $SINGLEMDS \
17527                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17528                      grep Blockcount | awk '{print $4}')
17529
17530         # Remove old files, some OI blocks will become idle.
17531         unlinkmany $myDIR/t- 20000
17532         rm -f $myDIR/guard
17533         # The OI file should become empty now
17534
17535         # Create new files, idle OI blocks should be reused.
17536         createmany -o $myDIR/t- 2000
17537         do_facet $SINGLEMDS sync
17538         # Make sure journal flushed.
17539         sleep 6
17540         local blk2=$(do_facet $SINGLEMDS \
17541                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17542                      grep Blockcount | awk '{print $4}')
17543
17544         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17545 }
17546 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17547
17548 test_229() { # LU-2482, LU-3448
17549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17550         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17551         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17552                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17553
17554         rm -f $DIR/$tfile
17555
17556         # Create a file with a released layout and stripe count 2.
17557         $MULTIOP $DIR/$tfile H2c ||
17558                 error "failed to create file with released layout"
17559
17560         $LFS getstripe -v $DIR/$tfile
17561
17562         local pattern=$($LFS getstripe -L $DIR/$tfile)
17563         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17564
17565         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17566                 error "getstripe"
17567         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17568         stat $DIR/$tfile || error "failed to stat released file"
17569
17570         chown $RUNAS_ID $DIR/$tfile ||
17571                 error "chown $RUNAS_ID $DIR/$tfile failed"
17572
17573         chgrp $RUNAS_ID $DIR/$tfile ||
17574                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17575
17576         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17577         rm $DIR/$tfile || error "failed to remove released file"
17578 }
17579 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17580
17581 test_230a() {
17582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17583         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17584         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17585                 skip "Need MDS version at least 2.11.52"
17586
17587         local MDTIDX=1
17588
17589         test_mkdir $DIR/$tdir
17590         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17591         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17592         [ $mdt_idx -ne 0 ] &&
17593                 error "create local directory on wrong MDT $mdt_idx"
17594
17595         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17596                         error "create remote directory failed"
17597         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17598         [ $mdt_idx -ne $MDTIDX ] &&
17599                 error "create remote directory on wrong MDT $mdt_idx"
17600
17601         createmany -o $DIR/$tdir/test_230/t- 10 ||
17602                 error "create files on remote directory failed"
17603         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17604         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17605         rm -r $DIR/$tdir || error "unlink remote directory failed"
17606 }
17607 run_test 230a "Create remote directory and files under the remote directory"
17608
17609 test_230b() {
17610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17612         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17613                 skip "Need MDS version at least 2.11.52"
17614
17615         local MDTIDX=1
17616         local mdt_index
17617         local i
17618         local file
17619         local pid
17620         local stripe_count
17621         local migrate_dir=$DIR/$tdir/migrate_dir
17622         local other_dir=$DIR/$tdir/other_dir
17623
17624         test_mkdir $DIR/$tdir
17625         test_mkdir -i0 -c1 $migrate_dir
17626         test_mkdir -i0 -c1 $other_dir
17627         for ((i=0; i<10; i++)); do
17628                 mkdir -p $migrate_dir/dir_${i}
17629                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17630                         error "create files under remote dir failed $i"
17631         done
17632
17633         cp /etc/passwd $migrate_dir/$tfile
17634         cp /etc/passwd $other_dir/$tfile
17635         chattr +SAD $migrate_dir
17636         chattr +SAD $migrate_dir/$tfile
17637
17638         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17639         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17640         local old_dir_mode=$(stat -c%f $migrate_dir)
17641         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17642
17643         mkdir -p $migrate_dir/dir_default_stripe2
17644         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17645         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17646
17647         mkdir -p $other_dir
17648         ln $migrate_dir/$tfile $other_dir/luna
17649         ln $migrate_dir/$tfile $migrate_dir/sofia
17650         ln $other_dir/$tfile $migrate_dir/david
17651         ln -s $migrate_dir/$tfile $other_dir/zachary
17652         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17653         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17654
17655         local len
17656         local lnktgt
17657
17658         # inline symlink
17659         for len in 58 59 60; do
17660                 lnktgt=$(str_repeat 'l' $len)
17661                 touch $migrate_dir/$lnktgt
17662                 ln -s $lnktgt $migrate_dir/${len}char_ln
17663         done
17664
17665         # PATH_MAX
17666         for len in 4094 4095; do
17667                 lnktgt=$(str_repeat 'l' $len)
17668                 ln -s $lnktgt $migrate_dir/${len}char_ln
17669         done
17670
17671         # NAME_MAX
17672         for len in 254 255; do
17673                 touch $migrate_dir/$(str_repeat 'l' $len)
17674         done
17675
17676         $LFS migrate -m $MDTIDX $migrate_dir ||
17677                 error "fails on migrating remote dir to MDT1"
17678
17679         echo "migratate to MDT1, then checking.."
17680         for ((i = 0; i < 10; i++)); do
17681                 for file in $(find $migrate_dir/dir_${i}); do
17682                         mdt_index=$($LFS getstripe -m $file)
17683                         # broken symlink getstripe will fail
17684                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17685                                 error "$file is not on MDT${MDTIDX}"
17686                 done
17687         done
17688
17689         # the multiple link file should still in MDT0
17690         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17691         [ $mdt_index == 0 ] ||
17692                 error "$file is not on MDT${MDTIDX}"
17693
17694         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17695         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17696                 error " expect $old_dir_flag get $new_dir_flag"
17697
17698         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17699         [ "$old_file_flag" = "$new_file_flag" ] ||
17700                 error " expect $old_file_flag get $new_file_flag"
17701
17702         local new_dir_mode=$(stat -c%f $migrate_dir)
17703         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17704                 error "expect mode $old_dir_mode get $new_dir_mode"
17705
17706         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17707         [ "$old_file_mode" = "$new_file_mode" ] ||
17708                 error "expect mode $old_file_mode get $new_file_mode"
17709
17710         diff /etc/passwd $migrate_dir/$tfile ||
17711                 error "$tfile different after migration"
17712
17713         diff /etc/passwd $other_dir/luna ||
17714                 error "luna different after migration"
17715
17716         diff /etc/passwd $migrate_dir/sofia ||
17717                 error "sofia different after migration"
17718
17719         diff /etc/passwd $migrate_dir/david ||
17720                 error "david different after migration"
17721
17722         diff /etc/passwd $other_dir/zachary ||
17723                 error "zachary different after migration"
17724
17725         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17726                 error "${tfile}_ln different after migration"
17727
17728         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17729                 error "${tfile}_ln_other different after migration"
17730
17731         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17732         [ $stripe_count = 2 ] ||
17733                 error "dir strpe_count $d != 2 after migration."
17734
17735         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17736         [ $stripe_count = 2 ] ||
17737                 error "file strpe_count $d != 2 after migration."
17738
17739         #migrate back to MDT0
17740         MDTIDX=0
17741
17742         $LFS migrate -m $MDTIDX $migrate_dir ||
17743                 error "fails on migrating remote dir to MDT0"
17744
17745         echo "migrate back to MDT0, checking.."
17746         for file in $(find $migrate_dir); do
17747                 mdt_index=$($LFS getstripe -m $file)
17748                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17749                         error "$file is not on MDT${MDTIDX}"
17750         done
17751
17752         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17753         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17754                 error " expect $old_dir_flag get $new_dir_flag"
17755
17756         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17757         [ "$old_file_flag" = "$new_file_flag" ] ||
17758                 error " expect $old_file_flag get $new_file_flag"
17759
17760         local new_dir_mode=$(stat -c%f $migrate_dir)
17761         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17762                 error "expect mode $old_dir_mode get $new_dir_mode"
17763
17764         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17765         [ "$old_file_mode" = "$new_file_mode" ] ||
17766                 error "expect mode $old_file_mode get $new_file_mode"
17767
17768         diff /etc/passwd ${migrate_dir}/$tfile ||
17769                 error "$tfile different after migration"
17770
17771         diff /etc/passwd ${other_dir}/luna ||
17772                 error "luna different after migration"
17773
17774         diff /etc/passwd ${migrate_dir}/sofia ||
17775                 error "sofia different after migration"
17776
17777         diff /etc/passwd ${other_dir}/zachary ||
17778                 error "zachary different after migration"
17779
17780         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17781                 error "${tfile}_ln different after migration"
17782
17783         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17784                 error "${tfile}_ln_other different after migration"
17785
17786         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17787         [ $stripe_count = 2 ] ||
17788                 error "dir strpe_count $d != 2 after migration."
17789
17790         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17791         [ $stripe_count = 2 ] ||
17792                 error "file strpe_count $d != 2 after migration."
17793
17794         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17795 }
17796 run_test 230b "migrate directory"
17797
17798 test_230c() {
17799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17800         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17801         remote_mds_nodsh && skip "remote MDS with nodsh"
17802         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17803                 skip "Need MDS version at least 2.11.52"
17804
17805         local MDTIDX=1
17806         local total=3
17807         local mdt_index
17808         local file
17809         local migrate_dir=$DIR/$tdir/migrate_dir
17810
17811         #If migrating directory fails in the middle, all entries of
17812         #the directory is still accessiable.
17813         test_mkdir $DIR/$tdir
17814         test_mkdir -i0 -c1 $migrate_dir
17815         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17816         stat $migrate_dir
17817         createmany -o $migrate_dir/f $total ||
17818                 error "create files under ${migrate_dir} failed"
17819
17820         # fail after migrating top dir, and this will fail only once, so the
17821         # first sub file migration will fail (currently f3), others succeed.
17822         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17823         do_facet mds1 lctl set_param fail_loc=0x1801
17824         local t=$(ls $migrate_dir | wc -l)
17825         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17826                 error "migrate should fail"
17827         local u=$(ls $migrate_dir | wc -l)
17828         [ "$u" == "$t" ] || error "$u != $t during migration"
17829
17830         # add new dir/file should succeed
17831         mkdir $migrate_dir/dir ||
17832                 error "mkdir failed under migrating directory"
17833         touch $migrate_dir/file ||
17834                 error "create file failed under migrating directory"
17835
17836         # add file with existing name should fail
17837         for file in $migrate_dir/f*; do
17838                 stat $file > /dev/null || error "stat $file failed"
17839                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17840                         error "open(O_CREAT|O_EXCL) $file should fail"
17841                 $MULTIOP $file m && error "create $file should fail"
17842                 touch $DIR/$tdir/remote_dir/$tfile ||
17843                         error "touch $tfile failed"
17844                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17845                         error "link $file should fail"
17846                 mdt_index=$($LFS getstripe -m $file)
17847                 if [ $mdt_index == 0 ]; then
17848                         # file failed to migrate is not allowed to rename to
17849                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17850                                 error "rename to $file should fail"
17851                 else
17852                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17853                                 error "rename to $file failed"
17854                 fi
17855                 echo hello >> $file || error "write $file failed"
17856         done
17857
17858         # resume migration with different options should fail
17859         $LFS migrate -m 0 $migrate_dir &&
17860                 error "migrate -m 0 $migrate_dir should fail"
17861
17862         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17863                 error "migrate -c 2 $migrate_dir should fail"
17864
17865         # resume migration should succeed
17866         $LFS migrate -m $MDTIDX $migrate_dir ||
17867                 error "migrate $migrate_dir failed"
17868
17869         echo "Finish migration, then checking.."
17870         for file in $(find $migrate_dir); do
17871                 mdt_index=$($LFS getstripe -m $file)
17872                 [ $mdt_index == $MDTIDX ] ||
17873                         error "$file is not on MDT${MDTIDX}"
17874         done
17875
17876         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17877 }
17878 run_test 230c "check directory accessiblity if migration failed"
17879
17880 test_230d() {
17881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17883         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17884                 skip "Need MDS version at least 2.11.52"
17885         # LU-11235
17886         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17887
17888         local migrate_dir=$DIR/$tdir/migrate_dir
17889         local old_index
17890         local new_index
17891         local old_count
17892         local new_count
17893         local new_hash
17894         local mdt_index
17895         local i
17896         local j
17897
17898         old_index=$((RANDOM % MDSCOUNT))
17899         old_count=$((MDSCOUNT - old_index))
17900         new_index=$((RANDOM % MDSCOUNT))
17901         new_count=$((MDSCOUNT - new_index))
17902         new_hash=1 # for all_char
17903
17904         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17905         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17906
17907         test_mkdir $DIR/$tdir
17908         test_mkdir -i $old_index -c $old_count $migrate_dir
17909
17910         for ((i=0; i<100; i++)); do
17911                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17912                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17913                         error "create files under remote dir failed $i"
17914         done
17915
17916         echo -n "Migrate from MDT$old_index "
17917         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17918         echo -n "to MDT$new_index"
17919         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17920         echo
17921
17922         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17923         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17924                 error "migrate remote dir error"
17925
17926         echo "Finish migration, then checking.."
17927         for file in $(find $migrate_dir); do
17928                 mdt_index=$($LFS getstripe -m $file)
17929                 if [ $mdt_index -lt $new_index ] ||
17930                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17931                         error "$file is on MDT$mdt_index"
17932                 fi
17933         done
17934
17935         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17936 }
17937 run_test 230d "check migrate big directory"
17938
17939 test_230e() {
17940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17942         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17943                 skip "Need MDS version at least 2.11.52"
17944
17945         local i
17946         local j
17947         local a_fid
17948         local b_fid
17949
17950         mkdir -p $DIR/$tdir
17951         mkdir $DIR/$tdir/migrate_dir
17952         mkdir $DIR/$tdir/other_dir
17953         touch $DIR/$tdir/migrate_dir/a
17954         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17955         ls $DIR/$tdir/other_dir
17956
17957         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17958                 error "migrate dir fails"
17959
17960         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17961         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17962
17963         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17964         [ $mdt_index == 0 ] || error "a is not on MDT0"
17965
17966         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17967                 error "migrate dir fails"
17968
17969         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17970         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17971
17972         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17973         [ $mdt_index == 1 ] || error "a is not on MDT1"
17974
17975         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17976         [ $mdt_index == 1 ] || error "b is not on MDT1"
17977
17978         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17979         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17980
17981         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17982
17983         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17984 }
17985 run_test 230e "migrate mulitple local link files"
17986
17987 test_230f() {
17988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17990         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17991                 skip "Need MDS version at least 2.11.52"
17992
17993         local a_fid
17994         local ln_fid
17995
17996         mkdir -p $DIR/$tdir
17997         mkdir $DIR/$tdir/migrate_dir
17998         $LFS mkdir -i1 $DIR/$tdir/other_dir
17999         touch $DIR/$tdir/migrate_dir/a
18000         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18001         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18002         ls $DIR/$tdir/other_dir
18003
18004         # a should be migrated to MDT1, since no other links on MDT0
18005         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18006                 error "#1 migrate dir fails"
18007         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18008         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18009         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18010         [ $mdt_index == 1 ] || error "a is not on MDT1"
18011
18012         # a should stay on MDT1, because it is a mulitple link file
18013         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18014                 error "#2 migrate dir fails"
18015         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18016         [ $mdt_index == 1 ] || error "a is not on MDT1"
18017
18018         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18019                 error "#3 migrate dir fails"
18020
18021         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18022         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18023         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18024
18025         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18026         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18027
18028         # a should be migrated to MDT0, since no other links on MDT1
18029         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18030                 error "#4 migrate dir fails"
18031         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18032         [ $mdt_index == 0 ] || error "a is not on MDT0"
18033
18034         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18035 }
18036 run_test 230f "migrate mulitple remote link files"
18037
18038 test_230g() {
18039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18040         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18041         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18042                 skip "Need MDS version at least 2.11.52"
18043
18044         mkdir -p $DIR/$tdir/migrate_dir
18045
18046         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18047                 error "migrating dir to non-exist MDT succeeds"
18048         true
18049 }
18050 run_test 230g "migrate dir to non-exist MDT"
18051
18052 test_230h() {
18053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18055         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18056                 skip "Need MDS version at least 2.11.52"
18057
18058         local mdt_index
18059
18060         mkdir -p $DIR/$tdir/migrate_dir
18061
18062         $LFS migrate -m1 $DIR &&
18063                 error "migrating mountpoint1 should fail"
18064
18065         $LFS migrate -m1 $DIR/$tdir/.. &&
18066                 error "migrating mountpoint2 should fail"
18067
18068         # same as mv
18069         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18070                 error "migrating $tdir/migrate_dir/.. should fail"
18071
18072         true
18073 }
18074 run_test 230h "migrate .. and root"
18075
18076 test_230i() {
18077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18078         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18079         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18080                 skip "Need MDS version at least 2.11.52"
18081
18082         mkdir -p $DIR/$tdir/migrate_dir
18083
18084         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18085                 error "migration fails with a tailing slash"
18086
18087         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18088                 error "migration fails with two tailing slashes"
18089 }
18090 run_test 230i "lfs migrate -m tolerates trailing slashes"
18091
18092 test_230j() {
18093         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18094         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18095                 skip "Need MDS version at least 2.11.52"
18096
18097         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18098         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18099                 error "create $tfile failed"
18100         cat /etc/passwd > $DIR/$tdir/$tfile
18101
18102         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18103
18104         cmp /etc/passwd $DIR/$tdir/$tfile ||
18105                 error "DoM file mismatch after migration"
18106 }
18107 run_test 230j "DoM file data not changed after dir migration"
18108
18109 test_230k() {
18110         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18111         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18112                 skip "Need MDS version at least 2.11.56"
18113
18114         local total=20
18115         local files_on_starting_mdt=0
18116
18117         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18118         $LFS getdirstripe $DIR/$tdir
18119         for i in $(seq $total); do
18120                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18121                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18122                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18123         done
18124
18125         echo "$files_on_starting_mdt files on MDT0"
18126
18127         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18128         $LFS getdirstripe $DIR/$tdir
18129
18130         files_on_starting_mdt=0
18131         for i in $(seq $total); do
18132                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18133                         error "file $tfile.$i mismatch after migration"
18134                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18135                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18136         done
18137
18138         echo "$files_on_starting_mdt files on MDT1 after migration"
18139         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18140
18141         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18142         $LFS getdirstripe $DIR/$tdir
18143
18144         files_on_starting_mdt=0
18145         for i in $(seq $total); do
18146                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18147                         error "file $tfile.$i mismatch after 2nd migration"
18148                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18149                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18150         done
18151
18152         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18153         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18154
18155         true
18156 }
18157 run_test 230k "file data not changed after dir migration"
18158
18159 test_230l() {
18160         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18161         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18162                 skip "Need MDS version at least 2.11.56"
18163
18164         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18165         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18166                 error "create files under remote dir failed $i"
18167         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18168 }
18169 run_test 230l "readdir between MDTs won't crash"
18170
18171 test_230m() {
18172         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18173         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18174                 skip "Need MDS version at least 2.11.56"
18175
18176         local MDTIDX=1
18177         local mig_dir=$DIR/$tdir/migrate_dir
18178         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18179         local shortstr="b"
18180         local val
18181
18182         echo "Creating files and dirs with xattrs"
18183         test_mkdir $DIR/$tdir
18184         test_mkdir -i0 -c1 $mig_dir
18185         mkdir $mig_dir/dir
18186         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18187                 error "cannot set xattr attr1 on dir"
18188         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18189                 error "cannot set xattr attr2 on dir"
18190         touch $mig_dir/dir/f0
18191         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18192                 error "cannot set xattr attr1 on file"
18193         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18194                 error "cannot set xattr attr2 on file"
18195         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18196         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18197         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18198         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18199         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18200         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18201         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18202         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18203         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18204
18205         echo "Migrating to MDT1"
18206         $LFS migrate -m $MDTIDX $mig_dir ||
18207                 error "fails on migrating dir to MDT1"
18208
18209         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18210         echo "Checking xattrs"
18211         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18212         [ "$val" = $longstr ] ||
18213                 error "expecting xattr1 $longstr on dir, found $val"
18214         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18215         [ "$val" = $shortstr ] ||
18216                 error "expecting xattr2 $shortstr on dir, found $val"
18217         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18218         [ "$val" = $longstr ] ||
18219                 error "expecting xattr1 $longstr on file, found $val"
18220         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18221         [ "$val" = $shortstr ] ||
18222                 error "expecting xattr2 $shortstr on file, found $val"
18223 }
18224 run_test 230m "xattrs not changed after dir migration"
18225
18226 test_230n() {
18227         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18228         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18229                 skip "Need MDS version at least 2.13.53"
18230
18231         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18232         cat /etc/hosts > $DIR/$tdir/$tfile
18233         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18234         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18235
18236         cmp /etc/hosts $DIR/$tdir/$tfile ||
18237                 error "File data mismatch after migration"
18238 }
18239 run_test 230n "Dir migration with mirrored file"
18240
18241 test_230o() {
18242         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18243         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18244                 skip "Need MDS version at least 2.13.52"
18245
18246         local mdts=$(comma_list $(mdts_nodes))
18247         local timeout=100
18248
18249         local restripe_status
18250         local delta
18251         local i
18252         local j
18253
18254         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18255
18256         # in case "crush" hash type is not set
18257         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18258
18259         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18260                            mdt.*MDT0000.enable_dir_restripe)
18261         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18262         stack_trap "do_nodes $mdts $LCTL set_param \
18263                     mdt.*.enable_dir_restripe=$restripe_status"
18264
18265         mkdir $DIR/$tdir
18266         createmany -m $DIR/$tdir/f 100 ||
18267                 error "create files under remote dir failed $i"
18268         createmany -d $DIR/$tdir/d 100 ||
18269                 error "create dirs under remote dir failed $i"
18270
18271         for i in $(seq 2 $MDSCOUNT); do
18272                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18273                 $LFS setdirstripe -c $i $DIR/$tdir ||
18274                         error "split -c $i $tdir failed"
18275                 wait_update $HOSTNAME \
18276                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18277                         error "dir split not finished"
18278                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18279                         awk '/migrate/ {sum += $2} END { print sum }')
18280                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18281                 # delta is around total_files/stripe_count
18282                 [ $delta -lt $((200 /(i - 1))) ] ||
18283                         error "$delta files migrated"
18284         done
18285 }
18286 run_test 230o "dir split"
18287
18288 test_230p() {
18289         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18290         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18291                 skip "Need MDS version at least 2.13.52"
18292
18293         local mdts=$(comma_list $(mdts_nodes))
18294         local timeout=100
18295
18296         local restripe_status
18297         local delta
18298         local i
18299         local j
18300
18301         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18302
18303         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18304
18305         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18306                            mdt.*MDT0000.enable_dir_restripe)
18307         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18308         stack_trap "do_nodes $mdts $LCTL set_param \
18309                     mdt.*.enable_dir_restripe=$restripe_status"
18310
18311         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18312         createmany -m $DIR/$tdir/f 100 ||
18313                 error "create files under remote dir failed $i"
18314         createmany -d $DIR/$tdir/d 100 ||
18315                 error "create dirs under remote dir failed $i"
18316
18317         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18318                 local mdt_hash="crush"
18319
18320                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18321                 $LFS setdirstripe -c $i $DIR/$tdir ||
18322                         error "split -c $i $tdir failed"
18323                 [ $i -eq 1 ] && mdt_hash="none"
18324                 wait_update $HOSTNAME \
18325                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18326                         error "dir merge not finished"
18327                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18328                         awk '/migrate/ {sum += $2} END { print sum }')
18329                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18330                 # delta is around total_files/stripe_count
18331                 [ $delta -lt $((200 / i)) ] ||
18332                         error "$delta files migrated"
18333         done
18334 }
18335 run_test 230p "dir merge"
18336
18337 test_230q() {
18338         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18339         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18340                 skip "Need MDS version at least 2.13.52"
18341
18342         local mdts=$(comma_list $(mdts_nodes))
18343         local saved_threshold=$(do_facet mds1 \
18344                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18345         local saved_delta=$(do_facet mds1 \
18346                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18347         local threshold=100
18348         local delta=2
18349         local total=0
18350         local stripe_count=0
18351         local stripe_index
18352         local nr_files
18353
18354         stack_trap "do_nodes $mdts $LCTL set_param \
18355                     mdt.*.dir_split_count=$saved_threshold"
18356         stack_trap "do_nodes $mdts $LCTL set_param \
18357                     mdt.*.dir_split_delta=$saved_delta"
18358         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18359         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18360         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18361         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18362         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18363         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18364
18365         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18366         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18367
18368         while [ $stripe_count -lt $MDSCOUNT ]; do
18369                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18370                         error "create sub files failed"
18371                 stat $DIR/$tdir > /dev/null
18372                 total=$((total + threshold * 3 / 2))
18373                 stripe_count=$((stripe_count + delta))
18374                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18375
18376                 wait_update $HOSTNAME \
18377                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18378                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18379
18380                 wait_update $HOSTNAME \
18381                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18382                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18383
18384                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18385                            grep -w $stripe_index | wc -l)
18386                 echo "$nr_files files on MDT$stripe_index after split"
18387                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18388                         error "$nr_files files on MDT$stripe_index after split"
18389
18390                 nr_files=$(ls $DIR/$tdir | wc -w)
18391                 [ $nr_files -eq $total ] ||
18392                         error "total sub files $nr_files != $total"
18393         done
18394 }
18395 run_test 230q "dir auto split"
18396
18397 test_230r() {
18398         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18399         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18400         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18401                 skip "Need MDS version at least 2.13.54"
18402
18403         # maximum amount of local locks:
18404         # parent striped dir - 2 locks
18405         # new stripe in parent to migrate to - 1 lock
18406         # source and target - 2 locks
18407         # Total 5 locks for regular file
18408         mkdir -p $DIR/$tdir
18409         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18410         touch $DIR/$tdir/dir1/eee
18411
18412         # create 4 hardlink for 4 more locks
18413         # Total: 9 locks > RS_MAX_LOCKS (8)
18414         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18415         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18416         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18417         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18418         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18419         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18420         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18421         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18422
18423         cancel_lru_locks mdc
18424
18425         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18426                 error "migrate dir fails"
18427
18428         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18429 }
18430 run_test 230r "migrate with too many local locks"
18431
18432 test_231a()
18433 {
18434         # For simplicity this test assumes that max_pages_per_rpc
18435         # is the same across all OSCs
18436         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18437         local bulk_size=$((max_pages * PAGE_SIZE))
18438         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18439                                        head -n 1)
18440
18441         mkdir -p $DIR/$tdir
18442         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18443                 error "failed to set stripe with -S ${brw_size}M option"
18444
18445         # clear the OSC stats
18446         $LCTL set_param osc.*.stats=0 &>/dev/null
18447         stop_writeback
18448
18449         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18450         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18451                 oflag=direct &>/dev/null || error "dd failed"
18452
18453         sync; sleep 1; sync # just to be safe
18454         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18455         if [ x$nrpcs != "x1" ]; then
18456                 $LCTL get_param osc.*.stats
18457                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18458         fi
18459
18460         start_writeback
18461         # Drop the OSC cache, otherwise we will read from it
18462         cancel_lru_locks osc
18463
18464         # clear the OSC stats
18465         $LCTL set_param osc.*.stats=0 &>/dev/null
18466
18467         # Client reads $bulk_size.
18468         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18469                 iflag=direct &>/dev/null || error "dd failed"
18470
18471         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18472         if [ x$nrpcs != "x1" ]; then
18473                 $LCTL get_param osc.*.stats
18474                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18475         fi
18476 }
18477 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18478
18479 test_231b() {
18480         mkdir -p $DIR/$tdir
18481         local i
18482         for i in {0..1023}; do
18483                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18484                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18485                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18486         done
18487         sync
18488 }
18489 run_test 231b "must not assert on fully utilized OST request buffer"
18490
18491 test_232a() {
18492         mkdir -p $DIR/$tdir
18493         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18494
18495         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18496         do_facet ost1 $LCTL set_param fail_loc=0x31c
18497
18498         # ignore dd failure
18499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18500
18501         do_facet ost1 $LCTL set_param fail_loc=0
18502         umount_client $MOUNT || error "umount failed"
18503         mount_client $MOUNT || error "mount failed"
18504         stop ost1 || error "cannot stop ost1"
18505         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18506 }
18507 run_test 232a "failed lock should not block umount"
18508
18509 test_232b() {
18510         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18511                 skip "Need MDS version at least 2.10.58"
18512
18513         mkdir -p $DIR/$tdir
18514         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18516         sync
18517         cancel_lru_locks osc
18518
18519         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18520         do_facet ost1 $LCTL set_param fail_loc=0x31c
18521
18522         # ignore failure
18523         $LFS data_version $DIR/$tdir/$tfile || true
18524
18525         do_facet ost1 $LCTL set_param fail_loc=0
18526         umount_client $MOUNT || error "umount failed"
18527         mount_client $MOUNT || error "mount failed"
18528         stop ost1 || error "cannot stop ost1"
18529         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18530 }
18531 run_test 232b "failed data version lock should not block umount"
18532
18533 test_233a() {
18534         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18535                 skip "Need MDS version at least 2.3.64"
18536         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18537
18538         local fid=$($LFS path2fid $MOUNT)
18539
18540         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18541                 error "cannot access $MOUNT using its FID '$fid'"
18542 }
18543 run_test 233a "checking that OBF of the FS root succeeds"
18544
18545 test_233b() {
18546         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18547                 skip "Need MDS version at least 2.5.90"
18548         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18549
18550         local fid=$($LFS path2fid $MOUNT/.lustre)
18551
18552         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18553                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18554
18555         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18556         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18557                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18558 }
18559 run_test 233b "checking that OBF of the FS .lustre succeeds"
18560
18561 test_234() {
18562         local p="$TMP/sanityN-$TESTNAME.parameters"
18563         save_lustre_params client "llite.*.xattr_cache" > $p
18564         lctl set_param llite.*.xattr_cache 1 ||
18565                 skip_env "xattr cache is not supported"
18566
18567         mkdir -p $DIR/$tdir || error "mkdir failed"
18568         touch $DIR/$tdir/$tfile || error "touch failed"
18569         # OBD_FAIL_LLITE_XATTR_ENOMEM
18570         $LCTL set_param fail_loc=0x1405
18571         getfattr -n user.attr $DIR/$tdir/$tfile &&
18572                 error "getfattr should have failed with ENOMEM"
18573         $LCTL set_param fail_loc=0x0
18574         rm -rf $DIR/$tdir
18575
18576         restore_lustre_params < $p
18577         rm -f $p
18578 }
18579 run_test 234 "xattr cache should not crash on ENOMEM"
18580
18581 test_235() {
18582         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18583                 skip "Need MDS version at least 2.4.52"
18584
18585         flock_deadlock $DIR/$tfile
18586         local RC=$?
18587         case $RC in
18588                 0)
18589                 ;;
18590                 124) error "process hangs on a deadlock"
18591                 ;;
18592                 *) error "error executing flock_deadlock $DIR/$tfile"
18593                 ;;
18594         esac
18595 }
18596 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18597
18598 #LU-2935
18599 test_236() {
18600         check_swap_layouts_support
18601
18602         local ref1=/etc/passwd
18603         local ref2=/etc/group
18604         local file1=$DIR/$tdir/f1
18605         local file2=$DIR/$tdir/f2
18606
18607         test_mkdir -c1 $DIR/$tdir
18608         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18609         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18610         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18611         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18612         local fd=$(free_fd)
18613         local cmd="exec $fd<>$file2"
18614         eval $cmd
18615         rm $file2
18616         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18617                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18618         cmd="exec $fd>&-"
18619         eval $cmd
18620         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18621
18622         #cleanup
18623         rm -rf $DIR/$tdir
18624 }
18625 run_test 236 "Layout swap on open unlinked file"
18626
18627 # LU-4659 linkea consistency
18628 test_238() {
18629         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18630                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18631                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18632                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18633
18634         touch $DIR/$tfile
18635         ln $DIR/$tfile $DIR/$tfile.lnk
18636         touch $DIR/$tfile.new
18637         mv $DIR/$tfile.new $DIR/$tfile
18638         local fid1=$($LFS path2fid $DIR/$tfile)
18639         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18640         local path1=$($LFS fid2path $FSNAME "$fid1")
18641         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18642         local path2=$($LFS fid2path $FSNAME "$fid2")
18643         [ $tfile.lnk == $path2 ] ||
18644                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18645         rm -f $DIR/$tfile*
18646 }
18647 run_test 238 "Verify linkea consistency"
18648
18649 test_239A() { # was test_239
18650         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18651                 skip "Need MDS version at least 2.5.60"
18652
18653         local list=$(comma_list $(mdts_nodes))
18654
18655         mkdir -p $DIR/$tdir
18656         createmany -o $DIR/$tdir/f- 5000
18657         unlinkmany $DIR/$tdir/f- 5000
18658         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18659                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18660         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18661                         osp.*MDT*.sync_in_flight" | calc_sum)
18662         [ "$changes" -eq 0 ] || error "$changes not synced"
18663 }
18664 run_test 239A "osp_sync test"
18665
18666 test_239a() { #LU-5297
18667         remote_mds_nodsh && skip "remote MDS with nodsh"
18668
18669         touch $DIR/$tfile
18670         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18671         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18672         chgrp $RUNAS_GID $DIR/$tfile
18673         wait_delete_completed
18674 }
18675 run_test 239a "process invalid osp sync record correctly"
18676
18677 test_239b() { #LU-5297
18678         remote_mds_nodsh && skip "remote MDS with nodsh"
18679
18680         touch $DIR/$tfile1
18681         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18682         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18683         chgrp $RUNAS_GID $DIR/$tfile1
18684         wait_delete_completed
18685         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18686         touch $DIR/$tfile2
18687         chgrp $RUNAS_GID $DIR/$tfile2
18688         wait_delete_completed
18689 }
18690 run_test 239b "process osp sync record with ENOMEM error correctly"
18691
18692 test_240() {
18693         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18694         remote_mds_nodsh && skip "remote MDS with nodsh"
18695
18696         mkdir -p $DIR/$tdir
18697
18698         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18699                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18700         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18701                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18702
18703         umount_client $MOUNT || error "umount failed"
18704         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18705         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18706         mount_client $MOUNT || error "failed to mount client"
18707
18708         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18709         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18710 }
18711 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18712
18713 test_241_bio() {
18714         local count=$1
18715         local bsize=$2
18716
18717         for LOOP in $(seq $count); do
18718                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18719                 cancel_lru_locks $OSC || true
18720         done
18721 }
18722
18723 test_241_dio() {
18724         local count=$1
18725         local bsize=$2
18726
18727         for LOOP in $(seq $1); do
18728                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18729                         2>/dev/null
18730         done
18731 }
18732
18733 test_241a() { # was test_241
18734         local bsize=$PAGE_SIZE
18735
18736         (( bsize < 40960 )) && bsize=40960
18737         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18738         ls -la $DIR/$tfile
18739         cancel_lru_locks $OSC
18740         test_241_bio 1000 $bsize &
18741         PID=$!
18742         test_241_dio 1000 $bsize
18743         wait $PID
18744 }
18745 run_test 241a "bio vs dio"
18746
18747 test_241b() {
18748         local bsize=$PAGE_SIZE
18749
18750         (( bsize < 40960 )) && bsize=40960
18751         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18752         ls -la $DIR/$tfile
18753         test_241_dio 1000 $bsize &
18754         PID=$!
18755         test_241_dio 1000 $bsize
18756         wait $PID
18757 }
18758 run_test 241b "dio vs dio"
18759
18760 test_242() {
18761         remote_mds_nodsh && skip "remote MDS with nodsh"
18762
18763         mkdir -p $DIR/$tdir
18764         touch $DIR/$tdir/$tfile
18765
18766         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18767         do_facet mds1 lctl set_param fail_loc=0x105
18768         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18769
18770         do_facet mds1 lctl set_param fail_loc=0
18771         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18772 }
18773 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18774
18775 test_243()
18776 {
18777         test_mkdir $DIR/$tdir
18778         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18779 }
18780 run_test 243 "various group lock tests"
18781
18782 test_244a()
18783 {
18784         test_mkdir $DIR/$tdir
18785         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18786         sendfile_grouplock $DIR/$tdir/$tfile || \
18787                 error "sendfile+grouplock failed"
18788         rm -rf $DIR/$tdir
18789 }
18790 run_test 244a "sendfile with group lock tests"
18791
18792 test_244b()
18793 {
18794         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18795
18796         local threads=50
18797         local size=$((1024*1024))
18798
18799         test_mkdir $DIR/$tdir
18800         for i in $(seq 1 $threads); do
18801                 local file=$DIR/$tdir/file_$((i / 10))
18802                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18803                 local pids[$i]=$!
18804         done
18805         for i in $(seq 1 $threads); do
18806                 wait ${pids[$i]}
18807         done
18808 }
18809 run_test 244b "multi-threaded write with group lock"
18810
18811 test_245() {
18812         local flagname="multi_mod_rpcs"
18813         local connect_data_name="max_mod_rpcs"
18814         local out
18815
18816         # check if multiple modify RPCs flag is set
18817         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18818                 grep "connect_flags:")
18819         echo "$out"
18820
18821         echo "$out" | grep -qw $flagname
18822         if [ $? -ne 0 ]; then
18823                 echo "connect flag $flagname is not set"
18824                 return
18825         fi
18826
18827         # check if multiple modify RPCs data is set
18828         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18829         echo "$out"
18830
18831         echo "$out" | grep -qw $connect_data_name ||
18832                 error "import should have connect data $connect_data_name"
18833 }
18834 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18835
18836 cleanup_247() {
18837         local submount=$1
18838
18839         trap 0
18840         umount_client $submount
18841         rmdir $submount
18842 }
18843
18844 test_247a() {
18845         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18846                 grep -q subtree ||
18847                 skip_env "Fileset feature is not supported"
18848
18849         local submount=${MOUNT}_$tdir
18850
18851         mkdir $MOUNT/$tdir
18852         mkdir -p $submount || error "mkdir $submount failed"
18853         FILESET="$FILESET/$tdir" mount_client $submount ||
18854                 error "mount $submount failed"
18855         trap "cleanup_247 $submount" EXIT
18856         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18857         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18858                 error "read $MOUNT/$tdir/$tfile failed"
18859         cleanup_247 $submount
18860 }
18861 run_test 247a "mount subdir as fileset"
18862
18863 test_247b() {
18864         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18865                 skip_env "Fileset feature is not supported"
18866
18867         local submount=${MOUNT}_$tdir
18868
18869         rm -rf $MOUNT/$tdir
18870         mkdir -p $submount || error "mkdir $submount failed"
18871         SKIP_FILESET=1
18872         FILESET="$FILESET/$tdir" mount_client $submount &&
18873                 error "mount $submount should fail"
18874         rmdir $submount
18875 }
18876 run_test 247b "mount subdir that dose not exist"
18877
18878 test_247c() {
18879         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18880                 skip_env "Fileset feature is not supported"
18881
18882         local submount=${MOUNT}_$tdir
18883
18884         mkdir -p $MOUNT/$tdir/dir1
18885         mkdir -p $submount || error "mkdir $submount failed"
18886         trap "cleanup_247 $submount" EXIT
18887         FILESET="$FILESET/$tdir" mount_client $submount ||
18888                 error "mount $submount failed"
18889         local fid=$($LFS path2fid $MOUNT/)
18890         $LFS fid2path $submount $fid && error "fid2path should fail"
18891         cleanup_247 $submount
18892 }
18893 run_test 247c "running fid2path outside subdirectory root"
18894
18895 test_247d() {
18896         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18897                 skip "Fileset feature is not supported"
18898
18899         local submount=${MOUNT}_$tdir
18900
18901         mkdir -p $MOUNT/$tdir/dir1
18902         mkdir -p $submount || error "mkdir $submount failed"
18903         FILESET="$FILESET/$tdir" mount_client $submount ||
18904                 error "mount $submount failed"
18905         trap "cleanup_247 $submount" EXIT
18906
18907         local td=$submount/dir1
18908         local fid=$($LFS path2fid $td)
18909         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18910
18911         # check that we get the same pathname back
18912         local rootpath
18913         local found
18914         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18915                 echo "$rootpath $fid"
18916                 found=$($LFS fid2path $rootpath "$fid")
18917                 [ -n "found" ] || error "fid2path should succeed"
18918                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18919         done
18920         # check wrong root path format
18921         rootpath=$submount"_wrong"
18922         found=$($LFS fid2path $rootpath "$fid")
18923         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18924
18925         cleanup_247 $submount
18926 }
18927 run_test 247d "running fid2path inside subdirectory root"
18928
18929 # LU-8037
18930 test_247e() {
18931         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18932                 grep -q subtree ||
18933                 skip "Fileset feature is not supported"
18934
18935         local submount=${MOUNT}_$tdir
18936
18937         mkdir $MOUNT/$tdir
18938         mkdir -p $submount || error "mkdir $submount failed"
18939         FILESET="$FILESET/.." mount_client $submount &&
18940                 error "mount $submount should fail"
18941         rmdir $submount
18942 }
18943 run_test 247e "mount .. as fileset"
18944
18945 test_247f() {
18946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18947         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18948                 skip "Need at least version 2.13.52"
18949         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18950                 grep -q subtree ||
18951                 skip "Fileset feature is not supported"
18952
18953         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18954         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18955                 error "mkdir remote failed"
18956         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18957         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18958                 error "mkdir striped failed"
18959         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18960
18961         local submount=${MOUNT}_$tdir
18962
18963         mkdir -p $submount || error "mkdir $submount failed"
18964
18965         local dir
18966         local fileset=$FILESET
18967
18968         for dir in $tdir/remote $tdir/remote/subdir \
18969                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18970                 FILESET="$fileset/$dir" mount_client $submount ||
18971                         error "mount $dir failed"
18972                 umount_client $submount
18973         done
18974 }
18975 run_test 247f "mount striped or remote directory as fileset"
18976
18977 test_248a() {
18978         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18979         [ -z "$fast_read_sav" ] && skip "no fast read support"
18980
18981         # create a large file for fast read verification
18982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18983
18984         # make sure the file is created correctly
18985         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18986                 { rm -f $DIR/$tfile; skip "file creation error"; }
18987
18988         echo "Test 1: verify that fast read is 4 times faster on cache read"
18989
18990         # small read with fast read enabled
18991         $LCTL set_param -n llite.*.fast_read=1
18992         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18993                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18994                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18995         # small read with fast read disabled
18996         $LCTL set_param -n llite.*.fast_read=0
18997         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18998                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18999                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19000
19001         # verify that fast read is 4 times faster for cache read
19002         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19003                 error_not_in_vm "fast read was not 4 times faster: " \
19004                            "$t_fast vs $t_slow"
19005
19006         echo "Test 2: verify the performance between big and small read"
19007         $LCTL set_param -n llite.*.fast_read=1
19008
19009         # 1k non-cache read
19010         cancel_lru_locks osc
19011         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19012                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19013                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19014
19015         # 1M non-cache read
19016         cancel_lru_locks osc
19017         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19018                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19019                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19020
19021         # verify that big IO is not 4 times faster than small IO
19022         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19023                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19024
19025         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19026         rm -f $DIR/$tfile
19027 }
19028 run_test 248a "fast read verification"
19029
19030 test_248b() {
19031         # Default short_io_bytes=16384, try both smaller and larger sizes.
19032         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19033         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19034         echo "bs=53248 count=113 normal buffered write"
19035         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19036                 error "dd of initial data file failed"
19037         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19038
19039         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19040         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19041                 error "dd with sync normal writes failed"
19042         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19043
19044         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19045         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19046                 error "dd with sync small writes failed"
19047         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19048
19049         cancel_lru_locks osc
19050
19051         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19052         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19053         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19054         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19055                 iflag=direct || error "dd with O_DIRECT small read failed"
19056         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19057         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19058                 error "compare $TMP/$tfile.1 failed"
19059
19060         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19061         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19062
19063         # just to see what the maximum tunable value is, and test parsing
19064         echo "test invalid parameter 2MB"
19065         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19066                 error "too-large short_io_bytes allowed"
19067         echo "test maximum parameter 512KB"
19068         # if we can set a larger short_io_bytes, run test regardless of version
19069         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19070                 # older clients may not allow setting it this large, that's OK
19071                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19072                         skip "Need at least client version 2.13.50"
19073                 error "medium short_io_bytes failed"
19074         fi
19075         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19076         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19077
19078         echo "test large parameter 64KB"
19079         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19080         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19081
19082         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19083         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19084                 error "dd with sync large writes failed"
19085         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19086
19087         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19088         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19089         num=$((113 * 4096 / PAGE_SIZE))
19090         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19091         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19092                 error "dd with O_DIRECT large writes failed"
19093         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19094                 error "compare $DIR/$tfile.3 failed"
19095
19096         cancel_lru_locks osc
19097
19098         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19099         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19100                 error "dd with O_DIRECT large read failed"
19101         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19102                 error "compare $TMP/$tfile.2 failed"
19103
19104         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19105         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19106                 error "dd with O_DIRECT large read failed"
19107         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19108                 error "compare $TMP/$tfile.3 failed"
19109 }
19110 run_test 248b "test short_io read and write for both small and large sizes"
19111
19112 test_249() { # LU-7890
19113         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19114                 skip "Need at least version 2.8.54"
19115
19116         rm -f $DIR/$tfile
19117         $LFS setstripe -c 1 $DIR/$tfile
19118         # Offset 2T == 4k * 512M
19119         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19120                 error "dd to 2T offset failed"
19121 }
19122 run_test 249 "Write above 2T file size"
19123
19124 test_250() {
19125         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19126          && skip "no 16TB file size limit on ZFS"
19127
19128         $LFS setstripe -c 1 $DIR/$tfile
19129         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19130         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19131         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19132         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19133                 conv=notrunc,fsync && error "append succeeded"
19134         return 0
19135 }
19136 run_test 250 "Write above 16T limit"
19137
19138 test_251() {
19139         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19140
19141         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19142         #Skip once - writing the first stripe will succeed
19143         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19144         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19145                 error "short write happened"
19146
19147         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19148         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19149                 error "short read happened"
19150
19151         rm -f $DIR/$tfile
19152 }
19153 run_test 251 "Handling short read and write correctly"
19154
19155 test_252() {
19156         remote_mds_nodsh && skip "remote MDS with nodsh"
19157         remote_ost_nodsh && skip "remote OST with nodsh"
19158         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19159                 skip_env "ldiskfs only test"
19160         fi
19161
19162         local tgt
19163         local dev
19164         local out
19165         local uuid
19166         local num
19167         local gen
19168
19169         # check lr_reader on OST0000
19170         tgt=ost1
19171         dev=$(facet_device $tgt)
19172         out=$(do_facet $tgt $LR_READER $dev)
19173         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19174         echo "$out"
19175         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19176         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19177                 error "Invalid uuid returned by $LR_READER on target $tgt"
19178         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19179
19180         # check lr_reader -c on MDT0000
19181         tgt=mds1
19182         dev=$(facet_device $tgt)
19183         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19184                 skip "$LR_READER does not support additional options"
19185         fi
19186         out=$(do_facet $tgt $LR_READER -c $dev)
19187         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19188         echo "$out"
19189         num=$(echo "$out" | grep -c "mdtlov")
19190         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19191                 error "Invalid number of mdtlov clients returned by $LR_READER"
19192         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19193
19194         # check lr_reader -cr on MDT0000
19195         out=$(do_facet $tgt $LR_READER -cr $dev)
19196         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19197         echo "$out"
19198         echo "$out" | grep -q "^reply_data:$" ||
19199                 error "$LR_READER should have returned 'reply_data' section"
19200         num=$(echo "$out" | grep -c "client_generation")
19201         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19202 }
19203 run_test 252 "check lr_reader tool"
19204
19205 test_253() {
19206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19207         remote_mds_nodsh && skip "remote MDS with nodsh"
19208         remote_mgs_nodsh && skip "remote MGS with nodsh"
19209
19210         local ostidx=0
19211         local rc=0
19212         local ost_name=$(ostname_from_index $ostidx)
19213
19214         # on the mdt's osc
19215         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19216         do_facet $SINGLEMDS $LCTL get_param -n \
19217                 osp.$mdtosc_proc1.reserved_mb_high ||
19218                 skip  "remote MDS does not support reserved_mb_high"
19219
19220         rm -rf $DIR/$tdir
19221         wait_mds_ost_sync
19222         wait_delete_completed
19223         mkdir $DIR/$tdir
19224
19225         pool_add $TESTNAME || error "Pool creation failed"
19226         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19227
19228         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19229                 error "Setstripe failed"
19230
19231         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19232
19233         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19234                     grep "watermarks")
19235         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19236
19237         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19238                         osp.$mdtosc_proc1.prealloc_status)
19239         echo "prealloc_status $oa_status"
19240
19241         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19242                 error "File creation should fail"
19243
19244         #object allocation was stopped, but we still able to append files
19245         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19246                 oflag=append || error "Append failed"
19247
19248         rm -f $DIR/$tdir/$tfile.0
19249
19250         # For this test, we want to delete the files we created to go out of
19251         # space but leave the watermark, so we remain nearly out of space
19252         ost_watermarks_enospc_delete_files $tfile $ostidx
19253
19254         wait_delete_completed
19255
19256         sleep_maxage
19257
19258         for i in $(seq 10 12); do
19259                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19260                         2>/dev/null || error "File creation failed after rm"
19261         done
19262
19263         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19264                         osp.$mdtosc_proc1.prealloc_status)
19265         echo "prealloc_status $oa_status"
19266
19267         if (( oa_status != 0 )); then
19268                 error "Object allocation still disable after rm"
19269         fi
19270 }
19271 run_test 253 "Check object allocation limit"
19272
19273 test_254() {
19274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19275         remote_mds_nodsh && skip "remote MDS with nodsh"
19276         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19277                 skip "MDS does not support changelog_size"
19278
19279         local cl_user
19280         local MDT0=$(facet_svc $SINGLEMDS)
19281
19282         changelog_register || error "changelog_register failed"
19283
19284         changelog_clear 0 || error "changelog_clear failed"
19285
19286         local size1=$(do_facet $SINGLEMDS \
19287                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19288         echo "Changelog size $size1"
19289
19290         rm -rf $DIR/$tdir
19291         $LFS mkdir -i 0 $DIR/$tdir
19292         # change something
19293         mkdir -p $DIR/$tdir/pics/2008/zachy
19294         touch $DIR/$tdir/pics/2008/zachy/timestamp
19295         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19296         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19297         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19298         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19299         rm $DIR/$tdir/pics/desktop.jpg
19300
19301         local size2=$(do_facet $SINGLEMDS \
19302                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19303         echo "Changelog size after work $size2"
19304
19305         (( $size2 > $size1 )) ||
19306                 error "new Changelog size=$size2 less than old size=$size1"
19307 }
19308 run_test 254 "Check changelog size"
19309
19310 ladvise_no_type()
19311 {
19312         local type=$1
19313         local file=$2
19314
19315         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19316                 awk -F: '{print $2}' | grep $type > /dev/null
19317         if [ $? -ne 0 ]; then
19318                 return 0
19319         fi
19320         return 1
19321 }
19322
19323 ladvise_no_ioctl()
19324 {
19325         local file=$1
19326
19327         lfs ladvise -a willread $file > /dev/null 2>&1
19328         if [ $? -eq 0 ]; then
19329                 return 1
19330         fi
19331
19332         lfs ladvise -a willread $file 2>&1 |
19333                 grep "Inappropriate ioctl for device" > /dev/null
19334         if [ $? -eq 0 ]; then
19335                 return 0
19336         fi
19337         return 1
19338 }
19339
19340 percent() {
19341         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19342 }
19343
19344 # run a random read IO workload
19345 # usage: random_read_iops <filename> <filesize> <iosize>
19346 random_read_iops() {
19347         local file=$1
19348         local fsize=$2
19349         local iosize=${3:-4096}
19350
19351         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19352                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19353 }
19354
19355 drop_file_oss_cache() {
19356         local file="$1"
19357         local nodes="$2"
19358
19359         $LFS ladvise -a dontneed $file 2>/dev/null ||
19360                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19361 }
19362
19363 ladvise_willread_performance()
19364 {
19365         local repeat=10
19366         local average_origin=0
19367         local average_cache=0
19368         local average_ladvise=0
19369
19370         for ((i = 1; i <= $repeat; i++)); do
19371                 echo "Iter $i/$repeat: reading without willread hint"
19372                 cancel_lru_locks osc
19373                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19374                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19375                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19376                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19377
19378                 cancel_lru_locks osc
19379                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19380                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19381                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19382
19383                 cancel_lru_locks osc
19384                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19385                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19386                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19387                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19388                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19389         done
19390         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19391         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19392         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19393
19394         speedup_cache=$(percent $average_cache $average_origin)
19395         speedup_ladvise=$(percent $average_ladvise $average_origin)
19396
19397         echo "Average uncached read: $average_origin"
19398         echo "Average speedup with OSS cached read: " \
19399                 "$average_cache = +$speedup_cache%"
19400         echo "Average speedup with ladvise willread: " \
19401                 "$average_ladvise = +$speedup_ladvise%"
19402
19403         local lowest_speedup=20
19404         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19405                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19406                         "got $average_cache%. Skipping ladvise willread check."
19407                 return 0
19408         fi
19409
19410         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19411         # it is still good to run until then to exercise 'ladvise willread'
19412         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19413                 [ "$ost1_FSTYPE" = "zfs" ] &&
19414                 echo "osd-zfs does not support dontneed or drop_caches" &&
19415                 return 0
19416
19417         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19418         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19419                 error_not_in_vm "Speedup with willread is less than " \
19420                         "$lowest_speedup%, got $average_ladvise%"
19421 }
19422
19423 test_255a() {
19424         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19425                 skip "lustre < 2.8.54 does not support ladvise "
19426         remote_ost_nodsh && skip "remote OST with nodsh"
19427
19428         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19429
19430         ladvise_no_type willread $DIR/$tfile &&
19431                 skip "willread ladvise is not supported"
19432
19433         ladvise_no_ioctl $DIR/$tfile &&
19434                 skip "ladvise ioctl is not supported"
19435
19436         local size_mb=100
19437         local size=$((size_mb * 1048576))
19438         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19439                 error "dd to $DIR/$tfile failed"
19440
19441         lfs ladvise -a willread $DIR/$tfile ||
19442                 error "Ladvise failed with no range argument"
19443
19444         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19445                 error "Ladvise failed with no -l or -e argument"
19446
19447         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19448                 error "Ladvise failed with only -e argument"
19449
19450         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19451                 error "Ladvise failed with only -l argument"
19452
19453         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19454                 error "End offset should not be smaller than start offset"
19455
19456         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19457                 error "End offset should not be equal to start offset"
19458
19459         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19460                 error "Ladvise failed with overflowing -s argument"
19461
19462         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19463                 error "Ladvise failed with overflowing -e argument"
19464
19465         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19466                 error "Ladvise failed with overflowing -l argument"
19467
19468         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19469                 error "Ladvise succeeded with conflicting -l and -e arguments"
19470
19471         echo "Synchronous ladvise should wait"
19472         local delay=4
19473 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19474         do_nodes $(comma_list $(osts_nodes)) \
19475                 $LCTL set_param fail_val=$delay fail_loc=0x237
19476
19477         local start_ts=$SECONDS
19478         lfs ladvise -a willread $DIR/$tfile ||
19479                 error "Ladvise failed with no range argument"
19480         local end_ts=$SECONDS
19481         local inteval_ts=$((end_ts - start_ts))
19482
19483         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19484                 error "Synchronous advice didn't wait reply"
19485         fi
19486
19487         echo "Asynchronous ladvise shouldn't wait"
19488         local start_ts=$SECONDS
19489         lfs ladvise -a willread -b $DIR/$tfile ||
19490                 error "Ladvise failed with no range argument"
19491         local end_ts=$SECONDS
19492         local inteval_ts=$((end_ts - start_ts))
19493
19494         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19495                 error "Asynchronous advice blocked"
19496         fi
19497
19498         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19499         ladvise_willread_performance
19500 }
19501 run_test 255a "check 'lfs ladvise -a willread'"
19502
19503 facet_meminfo() {
19504         local facet=$1
19505         local info=$2
19506
19507         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19508 }
19509
19510 test_255b() {
19511         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19512                 skip "lustre < 2.8.54 does not support ladvise "
19513         remote_ost_nodsh && skip "remote OST with nodsh"
19514
19515         lfs setstripe -c 1 -i 0 $DIR/$tfile
19516
19517         ladvise_no_type dontneed $DIR/$tfile &&
19518                 skip "dontneed ladvise is not supported"
19519
19520         ladvise_no_ioctl $DIR/$tfile &&
19521                 skip "ladvise ioctl is not supported"
19522
19523         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19524                 [ "$ost1_FSTYPE" = "zfs" ] &&
19525                 skip "zfs-osd does not support 'ladvise dontneed'"
19526
19527         local size_mb=100
19528         local size=$((size_mb * 1048576))
19529         # In order to prevent disturbance of other processes, only check 3/4
19530         # of the memory usage
19531         local kibibytes=$((size_mb * 1024 * 3 / 4))
19532
19533         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19534                 error "dd to $DIR/$tfile failed"
19535
19536         #force write to complete before dropping OST cache & checking memory
19537         sync
19538
19539         local total=$(facet_meminfo ost1 MemTotal)
19540         echo "Total memory: $total KiB"
19541
19542         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19543         local before_read=$(facet_meminfo ost1 Cached)
19544         echo "Cache used before read: $before_read KiB"
19545
19546         lfs ladvise -a willread $DIR/$tfile ||
19547                 error "Ladvise willread failed"
19548         local after_read=$(facet_meminfo ost1 Cached)
19549         echo "Cache used after read: $after_read KiB"
19550
19551         lfs ladvise -a dontneed $DIR/$tfile ||
19552                 error "Ladvise dontneed again failed"
19553         local no_read=$(facet_meminfo ost1 Cached)
19554         echo "Cache used after dontneed ladvise: $no_read KiB"
19555
19556         if [ $total -lt $((before_read + kibibytes)) ]; then
19557                 echo "Memory is too small, abort checking"
19558                 return 0
19559         fi
19560
19561         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19562                 error "Ladvise willread should use more memory" \
19563                         "than $kibibytes KiB"
19564         fi
19565
19566         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19567                 error "Ladvise dontneed should release more memory" \
19568                         "than $kibibytes KiB"
19569         fi
19570 }
19571 run_test 255b "check 'lfs ladvise -a dontneed'"
19572
19573 test_255c() {
19574         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19575                 skip "lustre < 2.10.50 does not support lockahead"
19576
19577         local count
19578         local new_count
19579         local difference
19580         local i
19581         local rc
19582
19583         test_mkdir -p $DIR/$tdir
19584         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19585
19586         #test 10 returns only success/failure
19587         i=10
19588         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19589         rc=$?
19590         if [ $rc -eq 255 ]; then
19591                 error "Ladvise test${i} failed, ${rc}"
19592         fi
19593
19594         #test 11 counts lock enqueue requests, all others count new locks
19595         i=11
19596         count=$(do_facet ost1 \
19597                 $LCTL get_param -n ost.OSS.ost.stats)
19598         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19599
19600         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19601         rc=$?
19602         if [ $rc -eq 255 ]; then
19603                 error "Ladvise test${i} failed, ${rc}"
19604         fi
19605
19606         new_count=$(do_facet ost1 \
19607                 $LCTL get_param -n ost.OSS.ost.stats)
19608         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19609                    awk '{ print $2 }')
19610
19611         difference="$((new_count - count))"
19612         if [ $difference -ne $rc ]; then
19613                 error "Ladvise test${i}, bad enqueue count, returned " \
19614                       "${rc}, actual ${difference}"
19615         fi
19616
19617         for i in $(seq 12 21); do
19618                 # If we do not do this, we run the risk of having too many
19619                 # locks and starting lock cancellation while we are checking
19620                 # lock counts.
19621                 cancel_lru_locks osc
19622
19623                 count=$($LCTL get_param -n \
19624                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19625
19626                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19627                 rc=$?
19628                 if [ $rc -eq 255 ]; then
19629                         error "Ladvise test ${i} failed, ${rc}"
19630                 fi
19631
19632                 new_count=$($LCTL get_param -n \
19633                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19634                 difference="$((new_count - count))"
19635
19636                 # Test 15 output is divided by 100 to map down to valid return
19637                 if [ $i -eq 15 ]; then
19638                         rc="$((rc * 100))"
19639                 fi
19640
19641                 if [ $difference -ne $rc ]; then
19642                         error "Ladvise test ${i}, bad lock count, returned " \
19643                               "${rc}, actual ${difference}"
19644                 fi
19645         done
19646
19647         #test 22 returns only success/failure
19648         i=22
19649         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19650         rc=$?
19651         if [ $rc -eq 255 ]; then
19652                 error "Ladvise test${i} failed, ${rc}"
19653         fi
19654 }
19655 run_test 255c "suite of ladvise lockahead tests"
19656
19657 test_256() {
19658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19659         remote_mds_nodsh && skip "remote MDS with nodsh"
19660         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19661         changelog_users $SINGLEMDS | grep "^cl" &&
19662                 skip "active changelog user"
19663
19664         local cl_user
19665         local cat_sl
19666         local mdt_dev
19667
19668         mdt_dev=$(mdsdevname 1)
19669         echo $mdt_dev
19670
19671         changelog_register || error "changelog_register failed"
19672
19673         rm -rf $DIR/$tdir
19674         mkdir -p $DIR/$tdir
19675
19676         changelog_clear 0 || error "changelog_clear failed"
19677
19678         # change something
19679         touch $DIR/$tdir/{1..10}
19680
19681         # stop the MDT
19682         stop $SINGLEMDS || error "Fail to stop MDT"
19683
19684         # remount the MDT
19685
19686         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19687
19688         #after mount new plainllog is used
19689         touch $DIR/$tdir/{11..19}
19690         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19691         stack_trap "rm -f $tmpfile"
19692         cat_sl=$(do_facet $SINGLEMDS "sync; \
19693                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19694                  llog_reader $tmpfile | grep -c type=1064553b")
19695         do_facet $SINGLEMDS llog_reader $tmpfile
19696
19697         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19698
19699         changelog_clear 0 || error "changelog_clear failed"
19700
19701         cat_sl=$(do_facet $SINGLEMDS "sync; \
19702                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19703                  llog_reader $tmpfile | grep -c type=1064553b")
19704
19705         if (( cat_sl == 2 )); then
19706                 error "Empty plain llog was not deleted from changelog catalog"
19707         elif (( cat_sl != 1 )); then
19708                 error "Active plain llog shouldn't be deleted from catalog"
19709         fi
19710 }
19711 run_test 256 "Check llog delete for empty and not full state"
19712
19713 test_257() {
19714         remote_mds_nodsh && skip "remote MDS with nodsh"
19715         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19716                 skip "Need MDS version at least 2.8.55"
19717
19718         test_mkdir $DIR/$tdir
19719
19720         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19721                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19722         stat $DIR/$tdir
19723
19724 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19725         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19726         local facet=mds$((mdtidx + 1))
19727         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19728         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19729
19730         stop $facet || error "stop MDS failed"
19731         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19732                 error "start MDS fail"
19733         wait_recovery_complete $facet
19734 }
19735 run_test 257 "xattr locks are not lost"
19736
19737 # Verify we take the i_mutex when security requires it
19738 test_258a() {
19739 #define OBD_FAIL_IMUTEX_SEC 0x141c
19740         $LCTL set_param fail_loc=0x141c
19741         touch $DIR/$tfile
19742         chmod u+s $DIR/$tfile
19743         chmod a+rwx $DIR/$tfile
19744         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19745         RC=$?
19746         if [ $RC -ne 0 ]; then
19747                 error "error, failed to take i_mutex, rc=$?"
19748         fi
19749         rm -f $DIR/$tfile
19750 }
19751 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19752
19753 # Verify we do NOT take the i_mutex in the normal case
19754 test_258b() {
19755 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19756         $LCTL set_param fail_loc=0x141d
19757         touch $DIR/$tfile
19758         chmod a+rwx $DIR
19759         chmod a+rw $DIR/$tfile
19760         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19761         RC=$?
19762         if [ $RC -ne 0 ]; then
19763                 error "error, took i_mutex unnecessarily, rc=$?"
19764         fi
19765         rm -f $DIR/$tfile
19766
19767 }
19768 run_test 258b "verify i_mutex security behavior"
19769
19770 test_259() {
19771         local file=$DIR/$tfile
19772         local before
19773         local after
19774
19775         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19776
19777         stack_trap "rm -f $file" EXIT
19778
19779         wait_delete_completed
19780         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19781         echo "before: $before"
19782
19783         $LFS setstripe -i 0 -c 1 $file
19784         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19785         sync_all_data
19786         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19787         echo "after write: $after"
19788
19789 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19790         do_facet ost1 $LCTL set_param fail_loc=0x2301
19791         $TRUNCATE $file 0
19792         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19793         echo "after truncate: $after"
19794
19795         stop ost1
19796         do_facet ost1 $LCTL set_param fail_loc=0
19797         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19798         sleep 2
19799         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19800         echo "after restart: $after"
19801         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19802                 error "missing truncate?"
19803
19804         return 0
19805 }
19806 run_test 259 "crash at delayed truncate"
19807
19808 test_260() {
19809 #define OBD_FAIL_MDC_CLOSE               0x806
19810         $LCTL set_param fail_loc=0x80000806
19811         touch $DIR/$tfile
19812
19813 }
19814 run_test 260 "Check mdc_close fail"
19815
19816 ### Data-on-MDT sanity tests ###
19817 test_270a() {
19818         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19819                 skip "Need MDS version at least 2.10.55 for DoM"
19820
19821         # create DoM file
19822         local dom=$DIR/$tdir/dom_file
19823         local tmp=$DIR/$tdir/tmp_file
19824
19825         mkdir -p $DIR/$tdir
19826
19827         # basic checks for DoM component creation
19828         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19829                 error "Can set MDT layout to non-first entry"
19830
19831         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19832                 error "Can define multiple entries as MDT layout"
19833
19834         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19835
19836         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19837         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19838         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19839
19840         local mdtidx=$($LFS getstripe -m $dom)
19841         local mdtname=MDT$(printf %04x $mdtidx)
19842         local facet=mds$((mdtidx + 1))
19843         local space_check=1
19844
19845         # Skip free space checks with ZFS
19846         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19847
19848         # write
19849         sync
19850         local size_tmp=$((65536 * 3))
19851         local mdtfree1=$(do_facet $facet \
19852                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19853
19854         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19855         # check also direct IO along write
19856         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19857         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19858         sync
19859         cmp $tmp $dom || error "file data is different"
19860         [ $(stat -c%s $dom) == $size_tmp ] ||
19861                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19862         if [ $space_check == 1 ]; then
19863                 local mdtfree2=$(do_facet $facet \
19864                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19865
19866                 # increase in usage from by $size_tmp
19867                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19868                         error "MDT free space wrong after write: " \
19869                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19870         fi
19871
19872         # truncate
19873         local size_dom=10000
19874
19875         $TRUNCATE $dom $size_dom
19876         [ $(stat -c%s $dom) == $size_dom ] ||
19877                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19878         if [ $space_check == 1 ]; then
19879                 mdtfree1=$(do_facet $facet \
19880                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19881                 # decrease in usage from $size_tmp to new $size_dom
19882                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19883                   $(((size_tmp - size_dom) / 1024)) ] ||
19884                         error "MDT free space is wrong after truncate: " \
19885                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19886         fi
19887
19888         # append
19889         cat $tmp >> $dom
19890         sync
19891         size_dom=$((size_dom + size_tmp))
19892         [ $(stat -c%s $dom) == $size_dom ] ||
19893                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19894         if [ $space_check == 1 ]; then
19895                 mdtfree2=$(do_facet $facet \
19896                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19897                 # increase in usage by $size_tmp from previous
19898                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19899                         error "MDT free space is wrong after append: " \
19900                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19901         fi
19902
19903         # delete
19904         rm $dom
19905         if [ $space_check == 1 ]; then
19906                 mdtfree1=$(do_facet $facet \
19907                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19908                 # decrease in usage by $size_dom from previous
19909                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19910                         error "MDT free space is wrong after removal: " \
19911                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19912         fi
19913
19914         # combined striping
19915         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19916                 error "Can't create DoM + OST striping"
19917
19918         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19919         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19920         # check also direct IO along write
19921         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19922         sync
19923         cmp $tmp $dom || error "file data is different"
19924         [ $(stat -c%s $dom) == $size_tmp ] ||
19925                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19926         rm $dom $tmp
19927
19928         return 0
19929 }
19930 run_test 270a "DoM: basic functionality tests"
19931
19932 test_270b() {
19933         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19934                 skip "Need MDS version at least 2.10.55"
19935
19936         local dom=$DIR/$tdir/dom_file
19937         local max_size=1048576
19938
19939         mkdir -p $DIR/$tdir
19940         $LFS setstripe -E $max_size -L mdt $dom
19941
19942         # truncate over the limit
19943         $TRUNCATE $dom $(($max_size + 1)) &&
19944                 error "successful truncate over the maximum size"
19945         # write over the limit
19946         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19947                 error "successful write over the maximum size"
19948         # append over the limit
19949         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19950         echo "12345" >> $dom && error "successful append over the maximum size"
19951         rm $dom
19952
19953         return 0
19954 }
19955 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19956
19957 test_270c() {
19958         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19959                 skip "Need MDS version at least 2.10.55"
19960
19961         mkdir -p $DIR/$tdir
19962         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19963
19964         # check files inherit DoM EA
19965         touch $DIR/$tdir/first
19966         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19967                 error "bad pattern"
19968         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19969                 error "bad stripe count"
19970         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19971                 error "bad stripe size"
19972
19973         # check directory inherits DoM EA and uses it as default
19974         mkdir $DIR/$tdir/subdir
19975         touch $DIR/$tdir/subdir/second
19976         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19977                 error "bad pattern in sub-directory"
19978         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19979                 error "bad stripe count in sub-directory"
19980         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19981                 error "bad stripe size in sub-directory"
19982         return 0
19983 }
19984 run_test 270c "DoM: DoM EA inheritance tests"
19985
19986 test_270d() {
19987         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19988                 skip "Need MDS version at least 2.10.55"
19989
19990         mkdir -p $DIR/$tdir
19991         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19992
19993         # inherit default DoM striping
19994         mkdir $DIR/$tdir/subdir
19995         touch $DIR/$tdir/subdir/f1
19996
19997         # change default directory striping
19998         $LFS setstripe -c 1 $DIR/$tdir/subdir
19999         touch $DIR/$tdir/subdir/f2
20000         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20001                 error "wrong default striping in file 2"
20002         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20003                 error "bad pattern in file 2"
20004         return 0
20005 }
20006 run_test 270d "DoM: change striping from DoM to RAID0"
20007
20008 test_270e() {
20009         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20010                 skip "Need MDS version at least 2.10.55"
20011
20012         mkdir -p $DIR/$tdir/dom
20013         mkdir -p $DIR/$tdir/norm
20014         DOMFILES=20
20015         NORMFILES=10
20016         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20017         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20018
20019         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20020         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20021
20022         # find DoM files by layout
20023         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20024         [ $NUM -eq  $DOMFILES ] ||
20025                 error "lfs find -L: found $NUM, expected $DOMFILES"
20026         echo "Test 1: lfs find 20 DOM files by layout: OK"
20027
20028         # there should be 1 dir with default DOM striping
20029         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20030         [ $NUM -eq  1 ] ||
20031                 error "lfs find -L: found $NUM, expected 1 dir"
20032         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20033
20034         # find DoM files by stripe size
20035         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20036         [ $NUM -eq  $DOMFILES ] ||
20037                 error "lfs find -S: found $NUM, expected $DOMFILES"
20038         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20039
20040         # find files by stripe offset except DoM files
20041         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20042         [ $NUM -eq  $NORMFILES ] ||
20043                 error "lfs find -i: found $NUM, expected $NORMFILES"
20044         echo "Test 5: lfs find no DOM files by stripe index: OK"
20045         return 0
20046 }
20047 run_test 270e "DoM: lfs find with DoM files test"
20048
20049 test_270f() {
20050         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20051                 skip "Need MDS version at least 2.10.55"
20052
20053         local mdtname=${FSNAME}-MDT0000-mdtlov
20054         local dom=$DIR/$tdir/dom_file
20055         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20056                                                 lod.$mdtname.dom_stripesize)
20057         local dom_limit=131072
20058
20059         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20060         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20061                                                 lod.$mdtname.dom_stripesize)
20062         [ ${dom_limit} -eq ${dom_current} ] ||
20063                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20064
20065         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20066         $LFS setstripe -d $DIR/$tdir
20067         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20068                 error "Can't set directory default striping"
20069
20070         # exceed maximum stripe size
20071         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20072                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20073         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20074                 error "Able to create DoM component size more than LOD limit"
20075
20076         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20077         dom_current=$(do_facet mds1 $LCTL get_param -n \
20078                                                 lod.$mdtname.dom_stripesize)
20079         [ 0 -eq ${dom_current} ] ||
20080                 error "Can't set zero DoM stripe limit"
20081         rm $dom
20082
20083         # attempt to create DoM file on server with disabled DoM should
20084         # remove DoM entry from layout and be succeed
20085         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20086                 error "Can't create DoM file (DoM is disabled)"
20087         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20088                 error "File has DoM component while DoM is disabled"
20089         rm $dom
20090
20091         # attempt to create DoM file with only DoM stripe should return error
20092         $LFS setstripe -E $dom_limit -L mdt $dom &&
20093                 error "Able to create DoM-only file while DoM is disabled"
20094
20095         # too low values to be aligned with smallest stripe size 64K
20096         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20097         dom_current=$(do_facet mds1 $LCTL get_param -n \
20098                                                 lod.$mdtname.dom_stripesize)
20099         [ 30000 -eq ${dom_current} ] &&
20100                 error "Can set too small DoM stripe limit"
20101
20102         # 64K is a minimal stripe size in Lustre, expect limit of that size
20103         [ 65536 -eq ${dom_current} ] ||
20104                 error "Limit is not set to 64K but ${dom_current}"
20105
20106         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20107         dom_current=$(do_facet mds1 $LCTL get_param -n \
20108                                                 lod.$mdtname.dom_stripesize)
20109         echo $dom_current
20110         [ 2147483648 -eq ${dom_current} ] &&
20111                 error "Can set too large DoM stripe limit"
20112
20113         do_facet mds1 $LCTL set_param -n \
20114                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20115         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20116                 error "Can't create DoM component size after limit change"
20117         do_facet mds1 $LCTL set_param -n \
20118                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20119         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20120                 error "Can't create DoM file after limit decrease"
20121         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20122                 error "Can create big DoM component after limit decrease"
20123         touch ${dom}_def ||
20124                 error "Can't create file with old default layout"
20125
20126         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20127         return 0
20128 }
20129 run_test 270f "DoM: maximum DoM stripe size checks"
20130
20131 test_270g() {
20132         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20133                 skip "Need MDS version at least 2.13.52"
20134         local dom=$DIR/$tdir/$tfile
20135
20136         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20137         local lodname=${FSNAME}-MDT0000-mdtlov
20138
20139         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20140         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20141         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20142         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20143
20144         local dom_limit=1024
20145         local dom_threshold="50%"
20146
20147         $LFS setstripe -d $DIR/$tdir
20148         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20149                 error "Can't set directory default striping"
20150
20151         do_facet mds1 $LCTL set_param -n \
20152                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20153         # set 0 threshold and create DOM file to change tunable stripesize
20154         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20155         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20156                 error "Failed to create $dom file"
20157         # now tunable dom_cur_stripesize should reach maximum
20158         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20159                                         lod.${lodname}.dom_stripesize_cur_kb)
20160         [[ $dom_current == $dom_limit ]] ||
20161                 error "Current DOM stripesize is not maximum"
20162         rm $dom
20163
20164         # set threshold for further tests
20165         do_facet mds1 $LCTL set_param -n \
20166                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20167         echo "DOM threshold is $dom_threshold free space"
20168         local dom_def
20169         local dom_set
20170         # Spoof bfree to exceed threshold
20171         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20172         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20173         for spfree in 40 20 0 15 30 55; do
20174                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20175                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20176                         error "Failed to create $dom file"
20177                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20178                                         lod.${lodname}.dom_stripesize_cur_kb)
20179                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20180                 [[ $dom_def != $dom_current ]] ||
20181                         error "Default stripe size was not changed"
20182                 if [[ $spfree > 0 ]] ; then
20183                         dom_set=$($LFS getstripe -S $dom)
20184                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20185                                 error "DOM component size is still old"
20186                 else
20187                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20188                                 error "DoM component is set with no free space"
20189                 fi
20190                 rm $dom
20191                 dom_current=$dom_def
20192         done
20193 }
20194 run_test 270g "DoM: default DoM stripe size depends on free space"
20195
20196 test_270h() {
20197         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20198                 skip "Need MDS version at least 2.13.53"
20199
20200         local mdtname=${FSNAME}-MDT0000-mdtlov
20201         local dom=$DIR/$tdir/$tfile
20202         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20203
20204         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20205         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20206
20207         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20208         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20209                 error "can't create OST file"
20210         # mirrored file with DOM entry in the second mirror
20211         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20212                 error "can't create mirror with DoM component"
20213
20214         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20215
20216         # DOM component in the middle and has other enries in the same mirror,
20217         # should succeed but lost DoM component
20218         $LFS setstripe --copy=${dom}_1 $dom ||
20219                 error "Can't create file from OST|DOM mirror layout"
20220         # check new file has no DoM layout after all
20221         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20222                 error "File has DoM component while DoM is disabled"
20223 }
20224 run_test 270h "DoM: DoM stripe removal when disabled on server"
20225
20226 test_271a() {
20227         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20228                 skip "Need MDS version at least 2.10.55"
20229
20230         local dom=$DIR/$tdir/dom
20231
20232         mkdir -p $DIR/$tdir
20233
20234         $LFS setstripe -E 1024K -L mdt $dom
20235
20236         lctl set_param -n mdc.*.stats=clear
20237         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20238         cat $dom > /dev/null
20239         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20240         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20241         ls $dom
20242         rm -f $dom
20243 }
20244 run_test 271a "DoM: data is cached for read after write"
20245
20246 test_271b() {
20247         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20248                 skip "Need MDS version at least 2.10.55"
20249
20250         local dom=$DIR/$tdir/dom
20251
20252         mkdir -p $DIR/$tdir
20253
20254         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20255
20256         lctl set_param -n mdc.*.stats=clear
20257         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20258         cancel_lru_locks mdc
20259         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20260         # second stat to check size is cached on client
20261         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20262         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20263         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20264         rm -f $dom
20265 }
20266 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20267
20268 test_271ba() {
20269         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20270                 skip "Need MDS version at least 2.10.55"
20271
20272         local dom=$DIR/$tdir/dom
20273
20274         mkdir -p $DIR/$tdir
20275
20276         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20277
20278         lctl set_param -n mdc.*.stats=clear
20279         lctl set_param -n osc.*.stats=clear
20280         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20281         cancel_lru_locks mdc
20282         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20283         # second stat to check size is cached on client
20284         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20285         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20286         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20287         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20288         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20289         rm -f $dom
20290 }
20291 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20292
20293
20294 get_mdc_stats() {
20295         local mdtidx=$1
20296         local param=$2
20297         local mdt=MDT$(printf %04x $mdtidx)
20298
20299         if [ -z $param ]; then
20300                 lctl get_param -n mdc.*$mdt*.stats
20301         else
20302                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20303         fi
20304 }
20305
20306 test_271c() {
20307         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20308                 skip "Need MDS version at least 2.10.55"
20309
20310         local dom=$DIR/$tdir/dom
20311
20312         mkdir -p $DIR/$tdir
20313
20314         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20315
20316         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20317         local facet=mds$((mdtidx + 1))
20318
20319         cancel_lru_locks mdc
20320         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20321         createmany -o $dom 1000
20322         lctl set_param -n mdc.*.stats=clear
20323         smalliomany -w $dom 1000 200
20324         get_mdc_stats $mdtidx
20325         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20326         # Each file has 1 open, 1 IO enqueues, total 2000
20327         # but now we have also +1 getxattr for security.capability, total 3000
20328         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20329         unlinkmany $dom 1000
20330
20331         cancel_lru_locks mdc
20332         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20333         createmany -o $dom 1000
20334         lctl set_param -n mdc.*.stats=clear
20335         smalliomany -w $dom 1000 200
20336         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20337         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20338         # for OPEN and IO lock.
20339         [ $((enq - enq_2)) -ge 1000 ] ||
20340                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20341         unlinkmany $dom 1000
20342         return 0
20343 }
20344 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20345
20346 cleanup_271def_tests() {
20347         trap 0
20348         rm -f $1
20349 }
20350
20351 test_271d() {
20352         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20353                 skip "Need MDS version at least 2.10.57"
20354
20355         local dom=$DIR/$tdir/dom
20356         local tmp=$TMP/$tfile
20357         trap "cleanup_271def_tests $tmp" EXIT
20358
20359         mkdir -p $DIR/$tdir
20360
20361         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20362
20363         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20364
20365         cancel_lru_locks mdc
20366         dd if=/dev/urandom of=$tmp bs=1000 count=1
20367         dd if=$tmp of=$dom bs=1000 count=1
20368         cancel_lru_locks mdc
20369
20370         cat /etc/hosts >> $tmp
20371         lctl set_param -n mdc.*.stats=clear
20372
20373         # append data to the same file it should update local page
20374         echo "Append to the same page"
20375         cat /etc/hosts >> $dom
20376         local num=$(get_mdc_stats $mdtidx ost_read)
20377         local ra=$(get_mdc_stats $mdtidx req_active)
20378         local rw=$(get_mdc_stats $mdtidx req_waittime)
20379
20380         [ -z $num ] || error "$num READ RPC occured"
20381         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20382         echo "... DONE"
20383
20384         # compare content
20385         cmp $tmp $dom || error "file miscompare"
20386
20387         cancel_lru_locks mdc
20388         lctl set_param -n mdc.*.stats=clear
20389
20390         echo "Open and read file"
20391         cat $dom > /dev/null
20392         local num=$(get_mdc_stats $mdtidx ost_read)
20393         local ra=$(get_mdc_stats $mdtidx req_active)
20394         local rw=$(get_mdc_stats $mdtidx req_waittime)
20395
20396         [ -z $num ] || error "$num READ RPC occured"
20397         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20398         echo "... DONE"
20399
20400         # compare content
20401         cmp $tmp $dom || error "file miscompare"
20402
20403         return 0
20404 }
20405 run_test 271d "DoM: read on open (1K file in reply buffer)"
20406
20407 test_271f() {
20408         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20409                 skip "Need MDS version at least 2.10.57"
20410
20411         local dom=$DIR/$tdir/dom
20412         local tmp=$TMP/$tfile
20413         trap "cleanup_271def_tests $tmp" EXIT
20414
20415         mkdir -p $DIR/$tdir
20416
20417         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20418
20419         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20420
20421         cancel_lru_locks mdc
20422         dd if=/dev/urandom of=$tmp bs=265000 count=1
20423         dd if=$tmp of=$dom bs=265000 count=1
20424         cancel_lru_locks mdc
20425         cat /etc/hosts >> $tmp
20426         lctl set_param -n mdc.*.stats=clear
20427
20428         echo "Append to the same page"
20429         cat /etc/hosts >> $dom
20430         local num=$(get_mdc_stats $mdtidx ost_read)
20431         local ra=$(get_mdc_stats $mdtidx req_active)
20432         local rw=$(get_mdc_stats $mdtidx req_waittime)
20433
20434         [ -z $num ] || error "$num READ RPC occured"
20435         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20436         echo "... DONE"
20437
20438         # compare content
20439         cmp $tmp $dom || error "file miscompare"
20440
20441         cancel_lru_locks mdc
20442         lctl set_param -n mdc.*.stats=clear
20443
20444         echo "Open and read file"
20445         cat $dom > /dev/null
20446         local num=$(get_mdc_stats $mdtidx ost_read)
20447         local ra=$(get_mdc_stats $mdtidx req_active)
20448         local rw=$(get_mdc_stats $mdtidx req_waittime)
20449
20450         [ -z $num ] && num=0
20451         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20452         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20453         echo "... DONE"
20454
20455         # compare content
20456         cmp $tmp $dom || error "file miscompare"
20457
20458         return 0
20459 }
20460 run_test 271f "DoM: read on open (200K file and read tail)"
20461
20462 test_271g() {
20463         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20464                 skip "Skipping due to old client or server version"
20465
20466         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20467         # to get layout
20468         $CHECKSTAT -t file $DIR1/$tfile
20469
20470         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20471         MULTIOP_PID=$!
20472         sleep 1
20473         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20474         $LCTL set_param fail_loc=0x80000314
20475         rm $DIR1/$tfile || error "Unlink fails"
20476         RC=$?
20477         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20478         [ $RC -eq 0 ] || error "Failed write to stale object"
20479 }
20480 run_test 271g "Discard DoM data vs client flush race"
20481
20482 test_272a() {
20483         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20484                 skip "Need MDS version at least 2.11.50"
20485
20486         local dom=$DIR/$tdir/dom
20487         mkdir -p $DIR/$tdir
20488
20489         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20490         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20491                 error "failed to write data into $dom"
20492         local old_md5=$(md5sum $dom)
20493
20494         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20495                 error "failed to migrate to the same DoM component"
20496
20497         local new_md5=$(md5sum $dom)
20498
20499         [ "$old_md5" == "$new_md5" ] ||
20500                 error "md5sum differ: $old_md5, $new_md5"
20501
20502         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20503                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20504 }
20505 run_test 272a "DoM migration: new layout with the same DOM component"
20506
20507 test_272b() {
20508         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20509                 skip "Need MDS version at least 2.11.50"
20510
20511         local dom=$DIR/$tdir/dom
20512         mkdir -p $DIR/$tdir
20513         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20514
20515         local mdtidx=$($LFS getstripe -m $dom)
20516         local mdtname=MDT$(printf %04x $mdtidx)
20517         local facet=mds$((mdtidx + 1))
20518
20519         local mdtfree1=$(do_facet $facet \
20520                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20521         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20522                 error "failed to write data into $dom"
20523         local old_md5=$(md5sum $dom)
20524         cancel_lru_locks mdc
20525         local mdtfree1=$(do_facet $facet \
20526                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20527
20528         $LFS migrate -c2 $dom ||
20529                 error "failed to migrate to the new composite layout"
20530         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20531                 error "MDT stripe was not removed"
20532
20533         cancel_lru_locks mdc
20534         local new_md5=$(md5sum $dom)
20535         [ "$old_md5" == "$new_md5" ] ||
20536                 error "$old_md5 != $new_md5"
20537
20538         # Skip free space checks with ZFS
20539         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20540                 local mdtfree2=$(do_facet $facet \
20541                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20542                 [ $mdtfree2 -gt $mdtfree1 ] ||
20543                         error "MDT space is not freed after migration"
20544         fi
20545         return 0
20546 }
20547 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20548
20549 test_272c() {
20550         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20551                 skip "Need MDS version at least 2.11.50"
20552
20553         local dom=$DIR/$tdir/$tfile
20554         mkdir -p $DIR/$tdir
20555         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20556
20557         local mdtidx=$($LFS getstripe -m $dom)
20558         local mdtname=MDT$(printf %04x $mdtidx)
20559         local facet=mds$((mdtidx + 1))
20560
20561         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20562                 error "failed to write data into $dom"
20563         local old_md5=$(md5sum $dom)
20564         cancel_lru_locks mdc
20565         local mdtfree1=$(do_facet $facet \
20566                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20567
20568         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20569                 error "failed to migrate to the new composite layout"
20570         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20571                 error "MDT stripe was not removed"
20572
20573         cancel_lru_locks mdc
20574         local new_md5=$(md5sum $dom)
20575         [ "$old_md5" == "$new_md5" ] ||
20576                 error "$old_md5 != $new_md5"
20577
20578         # Skip free space checks with ZFS
20579         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20580                 local mdtfree2=$(do_facet $facet \
20581                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20582                 [ $mdtfree2 -gt $mdtfree1 ] ||
20583                         error "MDS space is not freed after migration"
20584         fi
20585         return 0
20586 }
20587 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20588
20589 test_272d() {
20590         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20591                 skip "Need MDS version at least 2.12.55"
20592
20593         local dom=$DIR/$tdir/$tfile
20594         mkdir -p $DIR/$tdir
20595         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20596
20597         local mdtidx=$($LFS getstripe -m $dom)
20598         local mdtname=MDT$(printf %04x $mdtidx)
20599         local facet=mds$((mdtidx + 1))
20600
20601         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20602                 error "failed to write data into $dom"
20603         local old_md5=$(md5sum $dom)
20604         cancel_lru_locks mdc
20605         local mdtfree1=$(do_facet $facet \
20606                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20607
20608         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20609                 error "failed mirroring to the new composite layout"
20610         $LFS mirror resync $dom ||
20611                 error "failed mirror resync"
20612         $LFS mirror split --mirror-id 1 -d $dom ||
20613                 error "failed mirror split"
20614
20615         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20616                 error "MDT stripe was not removed"
20617
20618         cancel_lru_locks mdc
20619         local new_md5=$(md5sum $dom)
20620         [ "$old_md5" == "$new_md5" ] ||
20621                 error "$old_md5 != $new_md5"
20622
20623         # Skip free space checks with ZFS
20624         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20625                 local mdtfree2=$(do_facet $facet \
20626                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20627                 [ $mdtfree2 -gt $mdtfree1 ] ||
20628                         error "MDS space is not freed after DOM mirror deletion"
20629         fi
20630         return 0
20631 }
20632 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20633
20634 test_272e() {
20635         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20636                 skip "Need MDS version at least 2.12.55"
20637
20638         local dom=$DIR/$tdir/$tfile
20639         mkdir -p $DIR/$tdir
20640         $LFS setstripe -c 2 $dom
20641
20642         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20643                 error "failed to write data into $dom"
20644         local old_md5=$(md5sum $dom)
20645         cancel_lru_locks mdc
20646
20647         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20648                 error "failed mirroring to the DOM layout"
20649         $LFS mirror resync $dom ||
20650                 error "failed mirror resync"
20651         $LFS mirror split --mirror-id 1 -d $dom ||
20652                 error "failed mirror split"
20653
20654         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20655                 error "MDT stripe was not removed"
20656
20657         cancel_lru_locks mdc
20658         local new_md5=$(md5sum $dom)
20659         [ "$old_md5" == "$new_md5" ] ||
20660                 error "$old_md5 != $new_md5"
20661
20662         return 0
20663 }
20664 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20665
20666 test_272f() {
20667         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20668                 skip "Need MDS version at least 2.12.55"
20669
20670         local dom=$DIR/$tdir/$tfile
20671         mkdir -p $DIR/$tdir
20672         $LFS setstripe -c 2 $dom
20673
20674         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20675                 error "failed to write data into $dom"
20676         local old_md5=$(md5sum $dom)
20677         cancel_lru_locks mdc
20678
20679         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20680                 error "failed migrating to the DOM file"
20681
20682         cancel_lru_locks mdc
20683         local new_md5=$(md5sum $dom)
20684         [ "$old_md5" != "$new_md5" ] &&
20685                 error "$old_md5 != $new_md5"
20686
20687         return 0
20688 }
20689 run_test 272f "DoM migration: OST-striped file to DOM file"
20690
20691 test_273a() {
20692         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20693                 skip "Need MDS version at least 2.11.50"
20694
20695         # Layout swap cannot be done if either file has DOM component,
20696         # this will never be supported, migration should be used instead
20697
20698         local dom=$DIR/$tdir/$tfile
20699         mkdir -p $DIR/$tdir
20700
20701         $LFS setstripe -c2 ${dom}_plain
20702         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20703         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20704                 error "can swap layout with DoM component"
20705         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20706                 error "can swap layout with DoM component"
20707
20708         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20709         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20710                 error "can swap layout with DoM component"
20711         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20712                 error "can swap layout with DoM component"
20713         return 0
20714 }
20715 run_test 273a "DoM: layout swapping should fail with DOM"
20716
20717 test_275() {
20718         remote_ost_nodsh && skip "remote OST with nodsh"
20719         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20720                 skip "Need OST version >= 2.10.57"
20721
20722         local file=$DIR/$tfile
20723         local oss
20724
20725         oss=$(comma_list $(osts_nodes))
20726
20727         dd if=/dev/urandom of=$file bs=1M count=2 ||
20728                 error "failed to create a file"
20729         cancel_lru_locks osc
20730
20731         #lock 1
20732         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20733                 error "failed to read a file"
20734
20735 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20736         $LCTL set_param fail_loc=0x8000031f
20737
20738         cancel_lru_locks osc &
20739         sleep 1
20740
20741 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20742         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20743         #IO takes another lock, but matches the PENDING one
20744         #and places it to the IO RPC
20745         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20746                 error "failed to read a file with PENDING lock"
20747 }
20748 run_test 275 "Read on a canceled duplicate lock"
20749
20750 test_276() {
20751         remote_ost_nodsh && skip "remote OST with nodsh"
20752         local pid
20753
20754         do_facet ost1 "(while true; do \
20755                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20756                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20757         pid=$!
20758
20759         for LOOP in $(seq 20); do
20760                 stop ost1
20761                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20762         done
20763         kill -9 $pid
20764         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20765                 rm $TMP/sanity_276_pid"
20766 }
20767 run_test 276 "Race between mount and obd_statfs"
20768
20769 test_277() {
20770         $LCTL set_param ldlm.namespaces.*.lru_size=0
20771         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20772         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20773                         grep ^used_mb | awk '{print $2}')
20774         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20775         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20776                 oflag=direct conv=notrunc
20777         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20778                         grep ^used_mb | awk '{print $2}')
20779         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20780 }
20781 run_test 277 "Direct IO shall drop page cache"
20782
20783 test_278() {
20784         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20785         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20786         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20787                 skip "needs the same host for mdt1 mdt2" && return
20788
20789         local pid1
20790         local pid2
20791
20792 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20793         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20794         stop mds2 &
20795         pid2=$!
20796
20797         stop mds1
20798
20799         echo "Starting MDTs"
20800         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20801         wait $pid2
20802 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20803 #will return NULL
20804         do_facet mds2 $LCTL set_param fail_loc=0
20805
20806         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20807         wait_recovery_complete mds2
20808 }
20809 run_test 278 "Race starting MDS between MDTs stop/start"
20810
20811 test_280() {
20812         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20813                 skip "Need MGS version at least 2.13.52"
20814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20815         combined_mgs_mds || skip "needs combined MGS/MDT"
20816
20817         umount_client $MOUNT
20818 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20819         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20820
20821         mount_client $MOUNT &
20822         sleep 1
20823         stop mgs || error "stop mgs failed"
20824         #for a race mgs would crash
20825         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20826         mount_client $MOUNT || error "mount client failed"
20827 }
20828 run_test 280 "Race between MGS umount and client llog processing"
20829
20830 cleanup_test_300() {
20831         trap 0
20832         umask $SAVE_UMASK
20833 }
20834 test_striped_dir() {
20835         local mdt_index=$1
20836         local stripe_count
20837         local stripe_index
20838
20839         mkdir -p $DIR/$tdir
20840
20841         SAVE_UMASK=$(umask)
20842         trap cleanup_test_300 RETURN EXIT
20843
20844         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20845                                                 $DIR/$tdir/striped_dir ||
20846                 error "set striped dir error"
20847
20848         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20849         [ "$mode" = "755" ] || error "expect 755 got $mode"
20850
20851         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20852                 error "getdirstripe failed"
20853         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20854         if [ "$stripe_count" != "2" ]; then
20855                 error "1:stripe_count is $stripe_count, expect 2"
20856         fi
20857         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20858         if [ "$stripe_count" != "2" ]; then
20859                 error "2:stripe_count is $stripe_count, expect 2"
20860         fi
20861
20862         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20863         if [ "$stripe_index" != "$mdt_index" ]; then
20864                 error "stripe_index is $stripe_index, expect $mdt_index"
20865         fi
20866
20867         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20868                 error "nlink error after create striped dir"
20869
20870         mkdir $DIR/$tdir/striped_dir/a
20871         mkdir $DIR/$tdir/striped_dir/b
20872
20873         stat $DIR/$tdir/striped_dir/a ||
20874                 error "create dir under striped dir failed"
20875         stat $DIR/$tdir/striped_dir/b ||
20876                 error "create dir under striped dir failed"
20877
20878         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20879                 error "nlink error after mkdir"
20880
20881         rmdir $DIR/$tdir/striped_dir/a
20882         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20883                 error "nlink error after rmdir"
20884
20885         rmdir $DIR/$tdir/striped_dir/b
20886         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20887                 error "nlink error after rmdir"
20888
20889         chattr +i $DIR/$tdir/striped_dir
20890         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20891                 error "immutable flags not working under striped dir!"
20892         chattr -i $DIR/$tdir/striped_dir
20893
20894         rmdir $DIR/$tdir/striped_dir ||
20895                 error "rmdir striped dir error"
20896
20897         cleanup_test_300
20898
20899         true
20900 }
20901
20902 test_300a() {
20903         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20904                 skip "skipped for lustre < 2.7.0"
20905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20906         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20907
20908         test_striped_dir 0 || error "failed on striped dir on MDT0"
20909         test_striped_dir 1 || error "failed on striped dir on MDT0"
20910 }
20911 run_test 300a "basic striped dir sanity test"
20912
20913 test_300b() {
20914         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20915                 skip "skipped for lustre < 2.7.0"
20916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20918
20919         local i
20920         local mtime1
20921         local mtime2
20922         local mtime3
20923
20924         test_mkdir $DIR/$tdir || error "mkdir fail"
20925         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20926                 error "set striped dir error"
20927         for i in {0..9}; do
20928                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20929                 sleep 1
20930                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20931                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20932                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20933                 sleep 1
20934                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20935                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20936                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20937         done
20938         true
20939 }
20940 run_test 300b "check ctime/mtime for striped dir"
20941
20942 test_300c() {
20943         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20944                 skip "skipped for lustre < 2.7.0"
20945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20947
20948         local file_count
20949
20950         mkdir -p $DIR/$tdir
20951         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20952                 error "set striped dir error"
20953
20954         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20955                 error "chown striped dir failed"
20956
20957         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20958                 error "create 5k files failed"
20959
20960         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20961
20962         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20963
20964         rm -rf $DIR/$tdir
20965 }
20966 run_test 300c "chown && check ls under striped directory"
20967
20968 test_300d() {
20969         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20970                 skip "skipped for lustre < 2.7.0"
20971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20972         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20973
20974         local stripe_count
20975         local file
20976
20977         mkdir -p $DIR/$tdir
20978         $LFS setstripe -c 2 $DIR/$tdir
20979
20980         #local striped directory
20981         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20982                 error "set striped dir error"
20983         #look at the directories for debug purposes
20984         ls -l $DIR/$tdir
20985         $LFS getdirstripe $DIR/$tdir
20986         ls -l $DIR/$tdir/striped_dir
20987         $LFS getdirstripe $DIR/$tdir/striped_dir
20988         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20989                 error "create 10 files failed"
20990
20991         #remote striped directory
20992         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20993                 error "set striped dir error"
20994         #look at the directories for debug purposes
20995         ls -l $DIR/$tdir
20996         $LFS getdirstripe $DIR/$tdir
20997         ls -l $DIR/$tdir/remote_striped_dir
20998         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20999         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21000                 error "create 10 files failed"
21001
21002         for file in $(find $DIR/$tdir); do
21003                 stripe_count=$($LFS getstripe -c $file)
21004                 [ $stripe_count -eq 2 ] ||
21005                         error "wrong stripe $stripe_count for $file"
21006         done
21007
21008         rm -rf $DIR/$tdir
21009 }
21010 run_test 300d "check default stripe under striped directory"
21011
21012 test_300e() {
21013         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21014                 skip "Need MDS version at least 2.7.55"
21015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21016         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21017
21018         local stripe_count
21019         local file
21020
21021         mkdir -p $DIR/$tdir
21022
21023         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21024                 error "set striped dir error"
21025
21026         touch $DIR/$tdir/striped_dir/a
21027         touch $DIR/$tdir/striped_dir/b
21028         touch $DIR/$tdir/striped_dir/c
21029
21030         mkdir $DIR/$tdir/striped_dir/dir_a
21031         mkdir $DIR/$tdir/striped_dir/dir_b
21032         mkdir $DIR/$tdir/striped_dir/dir_c
21033
21034         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21035                 error "set striped adir under striped dir error"
21036
21037         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21038                 error "set striped bdir under striped dir error"
21039
21040         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21041                 error "set striped cdir under striped dir error"
21042
21043         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21044                 error "rename dir under striped dir fails"
21045
21046         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21047                 error "rename dir under different stripes fails"
21048
21049         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21050                 error "rename file under striped dir should succeed"
21051
21052         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21053                 error "rename dir under striped dir should succeed"
21054
21055         rm -rf $DIR/$tdir
21056 }
21057 run_test 300e "check rename under striped directory"
21058
21059 test_300f() {
21060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21062         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21063                 skip "Need MDS version at least 2.7.55"
21064
21065         local stripe_count
21066         local file
21067
21068         rm -rf $DIR/$tdir
21069         mkdir -p $DIR/$tdir
21070
21071         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21072                 error "set striped dir error"
21073
21074         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21075                 error "set striped dir error"
21076
21077         touch $DIR/$tdir/striped_dir/a
21078         mkdir $DIR/$tdir/striped_dir/dir_a
21079         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21080                 error "create striped dir under striped dir fails"
21081
21082         touch $DIR/$tdir/striped_dir1/b
21083         mkdir $DIR/$tdir/striped_dir1/dir_b
21084         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21085                 error "create striped dir under striped dir fails"
21086
21087         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21088                 error "rename dir under different striped dir should fail"
21089
21090         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21091                 error "rename striped dir under diff striped dir should fail"
21092
21093         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21094                 error "rename file under diff striped dirs fails"
21095
21096         rm -rf $DIR/$tdir
21097 }
21098 run_test 300f "check rename cross striped directory"
21099
21100 test_300_check_default_striped_dir()
21101 {
21102         local dirname=$1
21103         local default_count=$2
21104         local default_index=$3
21105         local stripe_count
21106         local stripe_index
21107         local dir_stripe_index
21108         local dir
21109
21110         echo "checking $dirname $default_count $default_index"
21111         $LFS setdirstripe -D -c $default_count -i $default_index \
21112                                 -t all_char $DIR/$tdir/$dirname ||
21113                 error "set default stripe on striped dir error"
21114         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21115         [ $stripe_count -eq $default_count ] ||
21116                 error "expect $default_count get $stripe_count for $dirname"
21117
21118         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21119         [ $stripe_index -eq $default_index ] ||
21120                 error "expect $default_index get $stripe_index for $dirname"
21121
21122         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21123                                                 error "create dirs failed"
21124
21125         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21126         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21127         for dir in $(find $DIR/$tdir/$dirname/*); do
21128                 stripe_count=$($LFS getdirstripe -c $dir)
21129                 [ $stripe_count -eq $default_count ] ||
21130                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21131                 error "stripe count $default_count != $stripe_count for $dir"
21132
21133                 stripe_index=$($LFS getdirstripe -i $dir)
21134                 [ $default_index -eq -1 ] ||
21135                         [ $stripe_index -eq $default_index ] ||
21136                         error "$stripe_index != $default_index for $dir"
21137
21138                 #check default stripe
21139                 stripe_count=$($LFS getdirstripe -D -c $dir)
21140                 [ $stripe_count -eq $default_count ] ||
21141                 error "default count $default_count != $stripe_count for $dir"
21142
21143                 stripe_index=$($LFS getdirstripe -D -i $dir)
21144                 [ $stripe_index -eq $default_index ] ||
21145                 error "default index $default_index != $stripe_index for $dir"
21146         done
21147         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21148 }
21149
21150 test_300g() {
21151         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21152         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21153                 skip "Need MDS version at least 2.7.55"
21154
21155         local dir
21156         local stripe_count
21157         local stripe_index
21158
21159         mkdir $DIR/$tdir
21160         mkdir $DIR/$tdir/normal_dir
21161
21162         #Checking when client cache stripe index
21163         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21164         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21165                 error "create striped_dir failed"
21166
21167         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21168                 error "create dir0 fails"
21169         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21170         [ $stripe_index -eq 0 ] ||
21171                 error "dir0 expect index 0 got $stripe_index"
21172
21173         mkdir $DIR/$tdir/striped_dir/dir1 ||
21174                 error "create dir1 fails"
21175         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21176         [ $stripe_index -eq 1 ] ||
21177                 error "dir1 expect index 1 got $stripe_index"
21178
21179         #check default stripe count/stripe index
21180         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21181         test_300_check_default_striped_dir normal_dir 1 0
21182         test_300_check_default_striped_dir normal_dir 2 1
21183         test_300_check_default_striped_dir normal_dir 2 -1
21184
21185         #delete default stripe information
21186         echo "delete default stripeEA"
21187         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21188                 error "set default stripe on striped dir error"
21189
21190         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21191         for dir in $(find $DIR/$tdir/normal_dir/*); do
21192                 stripe_count=$($LFS getdirstripe -c $dir)
21193                 [ $stripe_count -eq 0 ] ||
21194                         error "expect 1 get $stripe_count for $dir"
21195                 stripe_index=$($LFS getdirstripe -i $dir)
21196                 [ $stripe_index -eq 0 ] ||
21197                         error "expect 0 get $stripe_index for $dir"
21198         done
21199 }
21200 run_test 300g "check default striped directory for normal directory"
21201
21202 test_300h() {
21203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21204         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21205                 skip "Need MDS version at least 2.7.55"
21206
21207         local dir
21208         local stripe_count
21209
21210         mkdir $DIR/$tdir
21211         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21212                 error "set striped dir error"
21213
21214         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21215         test_300_check_default_striped_dir striped_dir 1 0
21216         test_300_check_default_striped_dir striped_dir 2 1
21217         test_300_check_default_striped_dir striped_dir 2 -1
21218
21219         #delete default stripe information
21220         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21221                 error "set default stripe on striped dir error"
21222
21223         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21224         for dir in $(find $DIR/$tdir/striped_dir/*); do
21225                 stripe_count=$($LFS getdirstripe -c $dir)
21226                 [ $stripe_count -eq 0 ] ||
21227                         error "expect 1 get $stripe_count for $dir"
21228         done
21229 }
21230 run_test 300h "check default striped directory for striped directory"
21231
21232 test_300i() {
21233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21235         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21236                 skip "Need MDS version at least 2.7.55"
21237
21238         local stripe_count
21239         local file
21240
21241         mkdir $DIR/$tdir
21242
21243         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21244                 error "set striped dir error"
21245
21246         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21247                 error "create files under striped dir failed"
21248
21249         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21250                 error "set striped hashdir error"
21251
21252         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21253                 error "create dir0 under hash dir failed"
21254         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21255                 error "create dir1 under hash dir failed"
21256
21257         # unfortunately, we need to umount to clear dir layout cache for now
21258         # once we fully implement dir layout, we can drop this
21259         umount_client $MOUNT || error "umount failed"
21260         mount_client $MOUNT || error "mount failed"
21261
21262         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21263         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21264         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21265
21266         #set the stripe to be unknown hash type
21267         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21268         $LCTL set_param fail_loc=0x1901
21269         for ((i = 0; i < 10; i++)); do
21270                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21271                         error "stat f-$i failed"
21272                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21273         done
21274
21275         touch $DIR/$tdir/striped_dir/f0 &&
21276                 error "create under striped dir with unknown hash should fail"
21277
21278         $LCTL set_param fail_loc=0
21279
21280         umount_client $MOUNT || error "umount failed"
21281         mount_client $MOUNT || error "mount failed"
21282
21283         return 0
21284 }
21285 run_test 300i "client handle unknown hash type striped directory"
21286
21287 test_300j() {
21288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21290         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21291                 skip "Need MDS version at least 2.7.55"
21292
21293         local stripe_count
21294         local file
21295
21296         mkdir $DIR/$tdir
21297
21298         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21299         $LCTL set_param fail_loc=0x1702
21300         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21301                 error "set striped dir error"
21302
21303         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21304                 error "create files under striped dir failed"
21305
21306         $LCTL set_param fail_loc=0
21307
21308         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21309
21310         return 0
21311 }
21312 run_test 300j "test large update record"
21313
21314 test_300k() {
21315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21317         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21318                 skip "Need MDS version at least 2.7.55"
21319
21320         # this test needs a huge transaction
21321         local kb
21322         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21323              osd*.$FSNAME-MDT0000.kbytestotal")
21324         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21325
21326         local stripe_count
21327         local file
21328
21329         mkdir $DIR/$tdir
21330
21331         #define OBD_FAIL_LARGE_STRIPE   0x1703
21332         $LCTL set_param fail_loc=0x1703
21333         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21334                 error "set striped dir error"
21335         $LCTL set_param fail_loc=0
21336
21337         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21338                 error "getstripeddir fails"
21339         rm -rf $DIR/$tdir/striped_dir ||
21340                 error "unlink striped dir fails"
21341
21342         return 0
21343 }
21344 run_test 300k "test large striped directory"
21345
21346 test_300l() {
21347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21349         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21350                 skip "Need MDS version at least 2.7.55"
21351
21352         local stripe_index
21353
21354         test_mkdir -p $DIR/$tdir/striped_dir
21355         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21356                         error "chown $RUNAS_ID failed"
21357         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21358                 error "set default striped dir failed"
21359
21360         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21361         $LCTL set_param fail_loc=0x80000158
21362         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21363
21364         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21365         [ $stripe_index -eq 1 ] ||
21366                 error "expect 1 get $stripe_index for $dir"
21367 }
21368 run_test 300l "non-root user to create dir under striped dir with stale layout"
21369
21370 test_300m() {
21371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21372         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21373         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21374                 skip "Need MDS version at least 2.7.55"
21375
21376         mkdir -p $DIR/$tdir/striped_dir
21377         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21378                 error "set default stripes dir error"
21379
21380         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21381
21382         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21383         [ $stripe_count -eq 0 ] ||
21384                         error "expect 0 get $stripe_count for a"
21385
21386         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21387                 error "set default stripes dir error"
21388
21389         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21390
21391         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21392         [ $stripe_count -eq 0 ] ||
21393                         error "expect 0 get $stripe_count for b"
21394
21395         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21396                 error "set default stripes dir error"
21397
21398         mkdir $DIR/$tdir/striped_dir/c &&
21399                 error "default stripe_index is invalid, mkdir c should fails"
21400
21401         rm -rf $DIR/$tdir || error "rmdir fails"
21402 }
21403 run_test 300m "setstriped directory on single MDT FS"
21404
21405 cleanup_300n() {
21406         local list=$(comma_list $(mdts_nodes))
21407
21408         trap 0
21409         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21410 }
21411
21412 test_300n() {
21413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21415         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21416                 skip "Need MDS version at least 2.7.55"
21417         remote_mds_nodsh && skip "remote MDS with nodsh"
21418
21419         local stripe_index
21420         local list=$(comma_list $(mdts_nodes))
21421
21422         trap cleanup_300n RETURN EXIT
21423         mkdir -p $DIR/$tdir
21424         chmod 777 $DIR/$tdir
21425         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21426                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21427                 error "create striped dir succeeds with gid=0"
21428
21429         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21430         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21431                 error "create striped dir fails with gid=-1"
21432
21433         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21434         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21435                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21436                 error "set default striped dir succeeds with gid=0"
21437
21438
21439         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21440         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21441                 error "set default striped dir fails with gid=-1"
21442
21443
21444         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21445         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21446                                         error "create test_dir fails"
21447         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21448                                         error "create test_dir1 fails"
21449         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21450                                         error "create test_dir2 fails"
21451         cleanup_300n
21452 }
21453 run_test 300n "non-root user to create dir under striped dir with default EA"
21454
21455 test_300o() {
21456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21457         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21458         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21459                 skip "Need MDS version at least 2.7.55"
21460
21461         local numfree1
21462         local numfree2
21463
21464         mkdir -p $DIR/$tdir
21465
21466         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21467         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21468         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21469                 skip "not enough free inodes $numfree1 $numfree2"
21470         fi
21471
21472         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21473         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21474         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21475                 skip "not enough free space $numfree1 $numfree2"
21476         fi
21477
21478         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21479                 error "setdirstripe fails"
21480
21481         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21482                 error "create dirs fails"
21483
21484         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21485         ls $DIR/$tdir/striped_dir > /dev/null ||
21486                 error "ls striped dir fails"
21487         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21488                 error "unlink big striped dir fails"
21489 }
21490 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21491
21492 test_300p() {
21493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21495         remote_mds_nodsh && skip "remote MDS with nodsh"
21496
21497         mkdir -p $DIR/$tdir
21498
21499         #define OBD_FAIL_OUT_ENOSPC     0x1704
21500         do_facet mds2 lctl set_param fail_loc=0x80001704
21501         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21502                  && error "create striped directory should fail"
21503
21504         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21505
21506         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21507         true
21508 }
21509 run_test 300p "create striped directory without space"
21510
21511 test_300q() {
21512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21514
21515         local fd=$(free_fd)
21516         local cmd="exec $fd<$tdir"
21517         cd $DIR
21518         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21519         eval $cmd
21520         cmd="exec $fd<&-"
21521         trap "eval $cmd" EXIT
21522         cd $tdir || error "cd $tdir fails"
21523         rmdir  ../$tdir || error "rmdir $tdir fails"
21524         mkdir local_dir && error "create dir succeeds"
21525         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21526         eval $cmd
21527         return 0
21528 }
21529 run_test 300q "create remote directory under orphan directory"
21530
21531 test_300r() {
21532         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21533                 skip "Need MDS version at least 2.7.55" && return
21534         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21535
21536         mkdir $DIR/$tdir
21537
21538         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21539                 error "set striped dir error"
21540
21541         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21542                 error "getstripeddir fails"
21543
21544         local stripe_count
21545         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21546                       awk '/lmv_stripe_count:/ { print $2 }')
21547
21548         [ $MDSCOUNT -ne $stripe_count ] &&
21549                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21550
21551         rm -rf $DIR/$tdir/striped_dir ||
21552                 error "unlink striped dir fails"
21553 }
21554 run_test 300r "test -1 striped directory"
21555
21556 prepare_remote_file() {
21557         mkdir $DIR/$tdir/src_dir ||
21558                 error "create remote source failed"
21559
21560         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21561                  error "cp to remote source failed"
21562         touch $DIR/$tdir/src_dir/a
21563
21564         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21565                 error "create remote target dir failed"
21566
21567         touch $DIR/$tdir/tgt_dir/b
21568
21569         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21570                 error "rename dir cross MDT failed!"
21571
21572         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21573                 error "src_child still exists after rename"
21574
21575         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21576                 error "missing file(a) after rename"
21577
21578         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21579                 error "diff after rename"
21580 }
21581
21582 test_310a() {
21583         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21585
21586         local remote_file=$DIR/$tdir/tgt_dir/b
21587
21588         mkdir -p $DIR/$tdir
21589
21590         prepare_remote_file || error "prepare remote file failed"
21591
21592         #open-unlink file
21593         $OPENUNLINK $remote_file $remote_file ||
21594                 error "openunlink $remote_file failed"
21595         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21596 }
21597 run_test 310a "open unlink remote file"
21598
21599 test_310b() {
21600         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21602
21603         local remote_file=$DIR/$tdir/tgt_dir/b
21604
21605         mkdir -p $DIR/$tdir
21606
21607         prepare_remote_file || error "prepare remote file failed"
21608
21609         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21610         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21611         $CHECKSTAT -t file $remote_file || error "check file failed"
21612 }
21613 run_test 310b "unlink remote file with multiple links while open"
21614
21615 test_310c() {
21616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21617         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21618
21619         local remote_file=$DIR/$tdir/tgt_dir/b
21620
21621         mkdir -p $DIR/$tdir
21622
21623         prepare_remote_file || error "prepare remote file failed"
21624
21625         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21626         multiop_bg_pause $remote_file O_uc ||
21627                         error "mulitop failed for remote file"
21628         MULTIPID=$!
21629         $MULTIOP $DIR/$tfile Ouc
21630         kill -USR1 $MULTIPID
21631         wait $MULTIPID
21632 }
21633 run_test 310c "open-unlink remote file with multiple links"
21634
21635 #LU-4825
21636 test_311() {
21637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21638         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21639         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21640                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21641         remote_mds_nodsh && skip "remote MDS with nodsh"
21642
21643         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21644         local mdts=$(comma_list $(mdts_nodes))
21645
21646         mkdir -p $DIR/$tdir
21647         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21648         createmany -o $DIR/$tdir/$tfile. 1000
21649
21650         # statfs data is not real time, let's just calculate it
21651         old_iused=$((old_iused + 1000))
21652
21653         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21654                         osp.*OST0000*MDT0000.create_count")
21655         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21656                                 osp.*OST0000*MDT0000.max_create_count")
21657         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21658
21659         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21660         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21661         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21662
21663         unlinkmany $DIR/$tdir/$tfile. 1000
21664
21665         do_nodes $mdts "$LCTL set_param -n \
21666                         osp.*OST0000*.max_create_count=$max_count"
21667         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21668                 do_nodes $mdts "$LCTL set_param -n \
21669                                 osp.*OST0000*.create_count=$count"
21670         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21671                         grep "=0" && error "create_count is zero"
21672
21673         local new_iused
21674         for i in $(seq 120); do
21675                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21676                 # system may be too busy to destroy all objs in time, use
21677                 # a somewhat small value to not fail autotest
21678                 [ $((old_iused - new_iused)) -gt 400 ] && break
21679                 sleep 1
21680         done
21681
21682         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21683         [ $((old_iused - new_iused)) -gt 400 ] ||
21684                 error "objs not destroyed after unlink"
21685 }
21686 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21687
21688 zfs_oid_to_objid()
21689 {
21690         local ost=$1
21691         local objid=$2
21692
21693         local vdevdir=$(dirname $(facet_vdevice $ost))
21694         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21695         local zfs_zapid=$(do_facet $ost $cmd |
21696                           grep -w "/O/0/d$((objid%32))" -C 5 |
21697                           awk '/Object/{getline; print $1}')
21698         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21699                           awk "/$objid = /"'{printf $3}')
21700
21701         echo $zfs_objid
21702 }
21703
21704 zfs_object_blksz() {
21705         local ost=$1
21706         local objid=$2
21707
21708         local vdevdir=$(dirname $(facet_vdevice $ost))
21709         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21710         local blksz=$(do_facet $ost $cmd $objid |
21711                       awk '/dblk/{getline; printf $4}')
21712
21713         case "${blksz: -1}" in
21714                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21715                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21716                 *) ;;
21717         esac
21718
21719         echo $blksz
21720 }
21721
21722 test_312() { # LU-4856
21723         remote_ost_nodsh && skip "remote OST with nodsh"
21724         [ "$ost1_FSTYPE" = "zfs" ] ||
21725                 skip_env "the test only applies to zfs"
21726
21727         local max_blksz=$(do_facet ost1 \
21728                           $ZFS get -p recordsize $(facet_device ost1) |
21729                           awk '!/VALUE/{print $3}')
21730
21731         # to make life a little bit easier
21732         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21733         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21734
21735         local tf=$DIR/$tdir/$tfile
21736         touch $tf
21737         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21738
21739         # Get ZFS object id
21740         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21741         # block size change by sequential overwrite
21742         local bs
21743
21744         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21745                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21746
21747                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21748                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21749         done
21750         rm -f $tf
21751
21752         # block size change by sequential append write
21753         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21754         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21755         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21756         local count
21757
21758         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21759                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21760                         oflag=sync conv=notrunc
21761
21762                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21763                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21764                         error "blksz error, actual $blksz, " \
21765                                 "expected: 2 * $count * $PAGE_SIZE"
21766         done
21767         rm -f $tf
21768
21769         # random write
21770         touch $tf
21771         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21772         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21773
21774         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21775         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21776         [ $blksz -eq $PAGE_SIZE ] ||
21777                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21778
21779         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21780         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21781         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21782
21783         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21784         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21785         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21786 }
21787 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21788
21789 test_313() {
21790         remote_ost_nodsh && skip "remote OST with nodsh"
21791
21792         local file=$DIR/$tfile
21793
21794         rm -f $file
21795         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21796
21797         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21798         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21799         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21800                 error "write should failed"
21801         do_facet ost1 "$LCTL set_param fail_loc=0"
21802         rm -f $file
21803 }
21804 run_test 313 "io should fail after last_rcvd update fail"
21805
21806 test_314() {
21807         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21808
21809         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21810         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21811         rm -f $DIR/$tfile
21812         wait_delete_completed
21813         do_facet ost1 "$LCTL set_param fail_loc=0"
21814 }
21815 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21816
21817 test_315() { # LU-618
21818         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21819
21820         local file=$DIR/$tfile
21821         rm -f $file
21822
21823         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21824                 error "multiop file write failed"
21825         $MULTIOP $file oO_RDONLY:r4063232_c &
21826         PID=$!
21827
21828         sleep 2
21829
21830         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21831         kill -USR1 $PID
21832
21833         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21834         rm -f $file
21835 }
21836 run_test 315 "read should be accounted"
21837
21838 test_316() {
21839         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21840         large_xattr_enabled || skip_env "ea_inode feature disabled"
21841
21842         rm -rf $DIR/$tdir/d
21843         mkdir -p $DIR/$tdir/d
21844         chown nobody $DIR/$tdir/d
21845         touch $DIR/$tdir/d/file
21846
21847         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21848 }
21849 run_test 316 "lfs mv"
21850
21851 test_317() {
21852         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21853                 skip "Need MDS version at least 2.11.53"
21854         if [ "$ost1_FSTYPE" == "zfs" ]; then
21855                 skip "LU-10370: no implementation for ZFS"
21856         fi
21857
21858         local trunc_sz
21859         local grant_blk_size
21860
21861         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21862                         awk '/grant_block_size:/ { print $2; exit; }')
21863         #
21864         # Create File of size 5M. Truncate it to below size's and verify
21865         # blocks count.
21866         #
21867         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21868                 error "Create file $DIR/$tfile failed"
21869         stack_trap "rm -f $DIR/$tfile" EXIT
21870
21871         for trunc_sz in 2097152 4097 4000 509 0; do
21872                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21873                         error "truncate $tfile to $trunc_sz failed"
21874                 local sz=$(stat --format=%s $DIR/$tfile)
21875                 local blk=$(stat --format=%b $DIR/$tfile)
21876                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21877                                      grant_blk_size) * 8))
21878
21879                 if [[ $blk -ne $trunc_blk ]]; then
21880                         $(which stat) $DIR/$tfile
21881                         error "Expected Block $trunc_blk got $blk for $tfile"
21882                 fi
21883
21884                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21885                         error "Expected Size $trunc_sz got $sz for $tfile"
21886         done
21887
21888         #
21889         # sparse file test
21890         # Create file with a hole and write actual two blocks. Block count
21891         # must be 16.
21892         #
21893         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21894                 conv=fsync || error "Create file : $DIR/$tfile"
21895
21896         # Calculate the final truncate size.
21897         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21898
21899         #
21900         # truncate to size $trunc_sz bytes. Strip the last block
21901         # The block count must drop to 8
21902         #
21903         $TRUNCATE $DIR/$tfile $trunc_sz ||
21904                 error "truncate $tfile to $trunc_sz failed"
21905
21906         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21907         sz=$(stat --format=%s $DIR/$tfile)
21908         blk=$(stat --format=%b $DIR/$tfile)
21909
21910         if [[ $blk -ne $trunc_bsz ]]; then
21911                 $(which stat) $DIR/$tfile
21912                 error "Expected Block $trunc_bsz got $blk for $tfile"
21913         fi
21914
21915         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21916                 error "Expected Size $trunc_sz got $sz for $tfile"
21917 }
21918 run_test 317 "Verify blocks get correctly update after truncate"
21919
21920 test_318() {
21921         local old_max_active=$($LCTL get_param -n \
21922                             llite.*.max_read_ahead_async_active 2>/dev/null)
21923
21924         $LCTL set_param llite.*.max_read_ahead_async_active=256
21925         local max_active=$($LCTL get_param -n \
21926                            llite.*.max_read_ahead_async_active 2>/dev/null)
21927         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21928
21929         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21930                 error "set max_read_ahead_async_active should succeed"
21931
21932         $LCTL set_param llite.*.max_read_ahead_async_active=512
21933         max_active=$($LCTL get_param -n \
21934                      llite.*.max_read_ahead_async_active 2>/dev/null)
21935         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21936
21937         # restore @max_active
21938         [ $old_max_active -ne 0 ] && $LCTL set_param \
21939                 llite.*.max_read_ahead_async_active=$old_max_active
21940
21941         local old_threshold=$($LCTL get_param -n \
21942                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21943         local max_per_file_mb=$($LCTL get_param -n \
21944                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21945
21946         local invalid=$(($max_per_file_mb + 1))
21947         $LCTL set_param \
21948                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21949                         && error "set $invalid should fail"
21950
21951         local valid=$(($invalid - 1))
21952         $LCTL set_param \
21953                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21954                         error "set $valid should succeed"
21955         local threshold=$($LCTL get_param -n \
21956                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21957         [ $threshold -eq $valid ] || error \
21958                 "expect threshold $valid got $threshold"
21959         $LCTL set_param \
21960                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21961 }
21962 run_test 318 "Verify async readahead tunables"
21963
21964 test_319() {
21965         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21966
21967         local before=$(date +%s)
21968         local evict
21969         local mdir=$DIR/$tdir
21970         local file=$mdir/xxx
21971
21972         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21973         touch $file
21974
21975 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21976         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21977         $LFS mv -m1 $file &
21978
21979         sleep 1
21980         dd if=$file of=/dev/null
21981         wait
21982         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21983           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21984
21985         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21986 }
21987 run_test 319 "lost lease lock on migrate error"
21988
21989 test_398a() { # LU-4198
21990         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21991         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21992
21993         # request a new lock on client
21994         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21995
21996         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21997         local lock_count=$($LCTL get_param -n \
21998                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21999         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22000
22001         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22002
22003         # no lock cached, should use lockless IO and not enqueue new lock
22004         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22005         lock_count=$($LCTL get_param -n \
22006                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22007         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22008 }
22009 run_test 398a "direct IO should cancel lock otherwise lockless"
22010
22011 test_398b() { # LU-4198
22012         which fio || skip_env "no fio installed"
22013         $LFS setstripe -c -1 $DIR/$tfile
22014
22015         local size=12
22016         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22017
22018         local njobs=4
22019         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22020         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22021                 --numjobs=$njobs --fallocate=none \
22022                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22023                 --filename=$DIR/$tfile &
22024         bg_pid=$!
22025
22026         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22027         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22028                 --numjobs=$njobs --fallocate=none \
22029                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22030                 --filename=$DIR/$tfile || true
22031         wait $bg_pid
22032
22033         rm -rf $DIR/$tfile
22034 }
22035 run_test 398b "DIO and buffer IO race"
22036
22037 test_398c() { # LU-4198
22038         which fio || skip_env "no fio installed"
22039
22040         saved_debug=$($LCTL get_param -n debug)
22041         $LCTL set_param debug=0
22042
22043         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22044         ((size /= 1024)) # by megabytes
22045         ((size /= 2)) # write half of the OST at most
22046         [ $size -gt 40 ] && size=40 #reduce test time anyway
22047
22048         $LFS setstripe -c 1 $DIR/$tfile
22049
22050         # it seems like ldiskfs reserves more space than necessary if the
22051         # writing blocks are not mapped, so it extends the file firstly
22052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22053         cancel_lru_locks osc
22054
22055         # clear and verify rpc_stats later
22056         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22057
22058         local njobs=4
22059         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22060         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22061                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22062                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22063                 --filename=$DIR/$tfile
22064         [ $? -eq 0 ] || error "fio write error"
22065
22066         [ $($LCTL get_param -n \
22067          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22068                 error "Locks were requested while doing AIO"
22069
22070         # get the percentage of 1-page I/O
22071         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22072                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22073                 awk '{print $7}')
22074         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22075
22076         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22077         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22078                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22079                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22080                 --filename=$DIR/$tfile
22081         [ $? -eq 0 ] || error "fio mixed read write error"
22082
22083         echo "AIO with large block size ${size}M"
22084         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22085                 --numjobs=1 --fallocate=none --ioengine=libaio \
22086                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22087                 --filename=$DIR/$tfile
22088         [ $? -eq 0 ] || error "fio large block size failed"
22089
22090         rm -rf $DIR/$tfile
22091         $LCTL set_param debug="$saved_debug"
22092 }
22093 run_test 398c "run fio to test AIO"
22094
22095 test_398d() { #  LU-13846
22096         test -f aiocp || skip_env "no aiocp installed"
22097         local aio_file=$DIR/aio_file
22098
22099         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22100
22101         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22102         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22103
22104         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22105
22106         # make sure we don't crash and fail properly
22107         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22108                 error "aio not aligned with PAGE SIZE should fail"
22109
22110         rm -rf $DIR/$tfile $aio_file
22111 }
22112 run_test 398d "run aiocp to verify block size > stripe size"
22113
22114 test_fake_rw() {
22115         local read_write=$1
22116         if [ "$read_write" = "write" ]; then
22117                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22118         elif [ "$read_write" = "read" ]; then
22119                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22120         else
22121                 error "argument error"
22122         fi
22123
22124         # turn off debug for performance testing
22125         local saved_debug=$($LCTL get_param -n debug)
22126         $LCTL set_param debug=0
22127
22128         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22129
22130         # get ost1 size - $FSNAME-OST0000
22131         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22132         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22133         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22134
22135         if [ "$read_write" = "read" ]; then
22136                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22137         fi
22138
22139         local start_time=$(date +%s.%N)
22140         $dd_cmd bs=1M count=$blocks oflag=sync ||
22141                 error "real dd $read_write error"
22142         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22143
22144         if [ "$read_write" = "write" ]; then
22145                 rm -f $DIR/$tfile
22146         fi
22147
22148         # define OBD_FAIL_OST_FAKE_RW           0x238
22149         do_facet ost1 $LCTL set_param fail_loc=0x238
22150
22151         local start_time=$(date +%s.%N)
22152         $dd_cmd bs=1M count=$blocks oflag=sync ||
22153                 error "fake dd $read_write error"
22154         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22155
22156         if [ "$read_write" = "write" ]; then
22157                 # verify file size
22158                 cancel_lru_locks osc
22159                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22160                         error "$tfile size not $blocks MB"
22161         fi
22162         do_facet ost1 $LCTL set_param fail_loc=0
22163
22164         echo "fake $read_write $duration_fake vs. normal $read_write" \
22165                 "$duration in seconds"
22166         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22167                 error_not_in_vm "fake write is slower"
22168
22169         $LCTL set_param -n debug="$saved_debug"
22170         rm -f $DIR/$tfile
22171 }
22172 test_399a() { # LU-7655 for OST fake write
22173         remote_ost_nodsh && skip "remote OST with nodsh"
22174
22175         test_fake_rw write
22176 }
22177 run_test 399a "fake write should not be slower than normal write"
22178
22179 test_399b() { # LU-8726 for OST fake read
22180         remote_ost_nodsh && skip "remote OST with nodsh"
22181         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22182                 skip_env "ldiskfs only test"
22183         fi
22184
22185         test_fake_rw read
22186 }
22187 run_test 399b "fake read should not be slower than normal read"
22188
22189 test_400a() { # LU-1606, was conf-sanity test_74
22190         if ! which $CC > /dev/null 2>&1; then
22191                 skip_env "$CC is not installed"
22192         fi
22193
22194         local extra_flags=''
22195         local out=$TMP/$tfile
22196         local prefix=/usr/include/lustre
22197         local prog
22198
22199         # Oleg removes c files in his test rig so test if any c files exist
22200         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22201                 skip_env "Needed c test files are missing"
22202
22203         if ! [[ -d $prefix ]]; then
22204                 # Assume we're running in tree and fixup the include path.
22205                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22206                 extra_flags+=" -L$LUSTRE/utils/.lib"
22207         fi
22208
22209         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22210                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22211                         error "client api broken"
22212         done
22213         rm -f $out
22214 }
22215 run_test 400a "Lustre client api program can compile and link"
22216
22217 test_400b() { # LU-1606, LU-5011
22218         local header
22219         local out=$TMP/$tfile
22220         local prefix=/usr/include/linux/lustre
22221
22222         # We use a hard coded prefix so that this test will not fail
22223         # when run in tree. There are headers in lustre/include/lustre/
22224         # that are not packaged (like lustre_idl.h) and have more
22225         # complicated include dependencies (like config.h and lnet/types.h).
22226         # Since this test about correct packaging we just skip them when
22227         # they don't exist (see below) rather than try to fixup cppflags.
22228
22229         if ! which $CC > /dev/null 2>&1; then
22230                 skip_env "$CC is not installed"
22231         fi
22232
22233         for header in $prefix/*.h; do
22234                 if ! [[ -f "$header" ]]; then
22235                         continue
22236                 fi
22237
22238                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22239                         continue # lustre_ioctl.h is internal header
22240                 fi
22241
22242                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22243                         error "cannot compile '$header'"
22244         done
22245         rm -f $out
22246 }
22247 run_test 400b "packaged headers can be compiled"
22248
22249 test_401a() { #LU-7437
22250         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22251         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22252
22253         #count the number of parameters by "list_param -R"
22254         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22255         #count the number of parameters by listing proc files
22256         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22257         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22258         echo "proc_dirs='$proc_dirs'"
22259         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22260         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22261                       sort -u | wc -l)
22262
22263         [ $params -eq $procs ] ||
22264                 error "found $params parameters vs. $procs proc files"
22265
22266         # test the list_param -D option only returns directories
22267         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22268         #count the number of parameters by listing proc directories
22269         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22270                 sort -u | wc -l)
22271
22272         [ $params -eq $procs ] ||
22273                 error "found $params parameters vs. $procs proc files"
22274 }
22275 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22276
22277 test_401b() {
22278         # jobid_var may not allow arbitrary values, so use jobid_name
22279         # if available
22280         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22281                 local testname=jobid_name tmp='testing%p'
22282         else
22283                 local testname=jobid_var tmp=testing
22284         fi
22285
22286         local save=$($LCTL get_param -n $testname)
22287
22288         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22289                 error "no error returned when setting bad parameters"
22290
22291         local jobid_new=$($LCTL get_param -n foe $testname baz)
22292         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22293
22294         $LCTL set_param -n fog=bam $testname=$save bat=fog
22295         local jobid_old=$($LCTL get_param -n foe $testname bag)
22296         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22297 }
22298 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22299
22300 test_401c() {
22301         # jobid_var may not allow arbitrary values, so use jobid_name
22302         # if available
22303         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22304                 local testname=jobid_name
22305         else
22306                 local testname=jobid_var
22307         fi
22308
22309         local jobid_var_old=$($LCTL get_param -n $testname)
22310         local jobid_var_new
22311
22312         $LCTL set_param $testname= &&
22313                 error "no error returned for 'set_param a='"
22314
22315         jobid_var_new=$($LCTL get_param -n $testname)
22316         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22317                 error "$testname was changed by setting without value"
22318
22319         $LCTL set_param $testname &&
22320                 error "no error returned for 'set_param a'"
22321
22322         jobid_var_new=$($LCTL get_param -n $testname)
22323         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22324                 error "$testname was changed by setting without value"
22325 }
22326 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22327
22328 test_401d() {
22329         # jobid_var may not allow arbitrary values, so use jobid_name
22330         # if available
22331         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22332                 local testname=jobid_name new_value='foo=bar%p'
22333         else
22334                 local testname=jobid_var new_valuie=foo=bar
22335         fi
22336
22337         local jobid_var_old=$($LCTL get_param -n $testname)
22338         local jobid_var_new
22339
22340         $LCTL set_param $testname=$new_value ||
22341                 error "'set_param a=b' did not accept a value containing '='"
22342
22343         jobid_var_new=$($LCTL get_param -n $testname)
22344         [[ "$jobid_var_new" == "$new_value" ]] ||
22345                 error "'set_param a=b' failed on a value containing '='"
22346
22347         # Reset the $testname to test the other format
22348         $LCTL set_param $testname=$jobid_var_old
22349         jobid_var_new=$($LCTL get_param -n $testname)
22350         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22351                 error "failed to reset $testname"
22352
22353         $LCTL set_param $testname $new_value ||
22354                 error "'set_param a b' did not accept a value containing '='"
22355
22356         jobid_var_new=$($LCTL get_param -n $testname)
22357         [[ "$jobid_var_new" == "$new_value" ]] ||
22358                 error "'set_param a b' failed on a value containing '='"
22359
22360         $LCTL set_param $testname $jobid_var_old
22361         jobid_var_new=$($LCTL get_param -n $testname)
22362         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22363                 error "failed to reset $testname"
22364 }
22365 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22366
22367 test_402() {
22368         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22369         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22370                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22371         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22372                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22373                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22374         remote_mds_nodsh && skip "remote MDS with nodsh"
22375
22376         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22377 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22378         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22379         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22380                 echo "Touch failed - OK"
22381 }
22382 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22383
22384 test_403() {
22385         local file1=$DIR/$tfile.1
22386         local file2=$DIR/$tfile.2
22387         local tfile=$TMP/$tfile
22388
22389         rm -f $file1 $file2 $tfile
22390
22391         touch $file1
22392         ln $file1 $file2
22393
22394         # 30 sec OBD_TIMEOUT in ll_getattr()
22395         # right before populating st_nlink
22396         $LCTL set_param fail_loc=0x80001409
22397         stat -c %h $file1 > $tfile &
22398
22399         # create an alias, drop all locks and reclaim the dentry
22400         < $file2
22401         cancel_lru_locks mdc
22402         cancel_lru_locks osc
22403         sysctl -w vm.drop_caches=2
22404
22405         wait
22406
22407         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22408
22409         rm -f $tfile $file1 $file2
22410 }
22411 run_test 403 "i_nlink should not drop to zero due to aliasing"
22412
22413 test_404() { # LU-6601
22414         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22415                 skip "Need server version newer than 2.8.52"
22416         remote_mds_nodsh && skip "remote MDS with nodsh"
22417
22418         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22419                 awk '/osp .*-osc-MDT/ { print $4}')
22420
22421         local osp
22422         for osp in $mosps; do
22423                 echo "Deactivate: " $osp
22424                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22425                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22426                         awk -vp=$osp '$4 == p { print $2 }')
22427                 [ $stat = IN ] || {
22428                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22429                         error "deactivate error"
22430                 }
22431                 echo "Activate: " $osp
22432                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22433                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22434                         awk -vp=$osp '$4 == p { print $2 }')
22435                 [ $stat = UP ] || {
22436                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22437                         error "activate error"
22438                 }
22439         done
22440 }
22441 run_test 404 "validate manual {de}activated works properly for OSPs"
22442
22443 test_405() {
22444         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22445         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22446                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22447                         skip "Layout swap lock is not supported"
22448
22449         check_swap_layouts_support
22450         check_swap_layout_no_dom $DIR
22451
22452         test_mkdir $DIR/$tdir
22453         swap_lock_test -d $DIR/$tdir ||
22454                 error "One layout swap locked test failed"
22455 }
22456 run_test 405 "Various layout swap lock tests"
22457
22458 test_406() {
22459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22460         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22461         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22463         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22464                 skip "Need MDS version at least 2.8.50"
22465
22466         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22467         local test_pool=$TESTNAME
22468
22469         pool_add $test_pool || error "pool_add failed"
22470         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22471                 error "pool_add_targets failed"
22472
22473         save_layout_restore_at_exit $MOUNT
22474
22475         # parent set default stripe count only, child will stripe from both
22476         # parent and fs default
22477         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22478                 error "setstripe $MOUNT failed"
22479         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22480         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22481         for i in $(seq 10); do
22482                 local f=$DIR/$tdir/$tfile.$i
22483                 touch $f || error "touch failed"
22484                 local count=$($LFS getstripe -c $f)
22485                 [ $count -eq $OSTCOUNT ] ||
22486                         error "$f stripe count $count != $OSTCOUNT"
22487                 local offset=$($LFS getstripe -i $f)
22488                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22489                 local size=$($LFS getstripe -S $f)
22490                 [ $size -eq $((def_stripe_size * 2)) ] ||
22491                         error "$f stripe size $size != $((def_stripe_size * 2))"
22492                 local pool=$($LFS getstripe -p $f)
22493                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22494         done
22495
22496         # change fs default striping, delete parent default striping, now child
22497         # will stripe from new fs default striping only
22498         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22499                 error "change $MOUNT default stripe failed"
22500         $LFS setstripe -c 0 $DIR/$tdir ||
22501                 error "delete $tdir default stripe failed"
22502         for i in $(seq 11 20); do
22503                 local f=$DIR/$tdir/$tfile.$i
22504                 touch $f || error "touch $f failed"
22505                 local count=$($LFS getstripe -c $f)
22506                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22507                 local offset=$($LFS getstripe -i $f)
22508                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22509                 local size=$($LFS getstripe -S $f)
22510                 [ $size -eq $def_stripe_size ] ||
22511                         error "$f stripe size $size != $def_stripe_size"
22512                 local pool=$($LFS getstripe -p $f)
22513                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22514         done
22515
22516         unlinkmany $DIR/$tdir/$tfile. 1 20
22517
22518         local f=$DIR/$tdir/$tfile
22519         pool_remove_all_targets $test_pool $f
22520         pool_remove $test_pool $f
22521 }
22522 run_test 406 "DNE support fs default striping"
22523
22524 test_407() {
22525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22526         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22527                 skip "Need MDS version at least 2.8.55"
22528         remote_mds_nodsh && skip "remote MDS with nodsh"
22529
22530         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22531                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22532         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22533                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22534         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22535
22536         #define OBD_FAIL_DT_TXN_STOP    0x2019
22537         for idx in $(seq $MDSCOUNT); do
22538                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22539         done
22540         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22541         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22542                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22543         true
22544 }
22545 run_test 407 "transaction fail should cause operation fail"
22546
22547 test_408() {
22548         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22549
22550         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22551         lctl set_param fail_loc=0x8000040a
22552         # let ll_prepare_partial_page() fail
22553         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22554
22555         rm -f $DIR/$tfile
22556
22557         # create at least 100 unused inodes so that
22558         # shrink_icache_memory(0) should not return 0
22559         touch $DIR/$tfile-{0..100}
22560         rm -f $DIR/$tfile-{0..100}
22561         sync
22562
22563         echo 2 > /proc/sys/vm/drop_caches
22564 }
22565 run_test 408 "drop_caches should not hang due to page leaks"
22566
22567 test_409()
22568 {
22569         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22570
22571         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22572         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22573         touch $DIR/$tdir/guard || error "(2) Fail to create"
22574
22575         local PREFIX=$(str_repeat 'A' 128)
22576         echo "Create 1K hard links start at $(date)"
22577         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22578                 error "(3) Fail to hard link"
22579
22580         echo "Links count should be right although linkEA overflow"
22581         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22582         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22583         [ $linkcount -eq 1001 ] ||
22584                 error "(5) Unexpected hard links count: $linkcount"
22585
22586         echo "List all links start at $(date)"
22587         ls -l $DIR/$tdir/foo > /dev/null ||
22588                 error "(6) Fail to list $DIR/$tdir/foo"
22589
22590         echo "Unlink hard links start at $(date)"
22591         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22592                 error "(7) Fail to unlink"
22593         echo "Unlink hard links finished at $(date)"
22594 }
22595 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22596
22597 test_410()
22598 {
22599         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22600                 skip "Need client version at least 2.9.59"
22601         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22602                 skip "Need MODULES build"
22603
22604         # Create a file, and stat it from the kernel
22605         local testfile=$DIR/$tfile
22606         touch $testfile
22607
22608         local run_id=$RANDOM
22609         local my_ino=$(stat --format "%i" $testfile)
22610
22611         # Try to insert the module. This will always fail as the
22612         # module is designed to not be inserted.
22613         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22614             &> /dev/null
22615
22616         # Anything but success is a test failure
22617         dmesg | grep -q \
22618             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22619             error "no inode match"
22620 }
22621 run_test 410 "Test inode number returned from kernel thread"
22622
22623 cleanup_test411_cgroup() {
22624         trap 0
22625         rmdir "$1"
22626 }
22627
22628 test_411() {
22629         local cg_basedir=/sys/fs/cgroup/memory
22630         # LU-9966
22631         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22632                 skip "no setup for cgroup"
22633
22634         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22635                 error "test file creation failed"
22636         cancel_lru_locks osc
22637
22638         # Create a very small memory cgroup to force a slab allocation error
22639         local cgdir=$cg_basedir/osc_slab_alloc
22640         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22641         trap "cleanup_test411_cgroup $cgdir" EXIT
22642         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22643         echo 1M > $cgdir/memory.limit_in_bytes
22644
22645         # Should not LBUG, just be killed by oom-killer
22646         # dd will return 0 even allocation failure in some environment.
22647         # So don't check return value
22648         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22649         cleanup_test411_cgroup $cgdir
22650
22651         return 0
22652 }
22653 run_test 411 "Slab allocation error with cgroup does not LBUG"
22654
22655 test_412() {
22656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22657         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22658                 skip "Need server version at least 2.10.55"
22659         fi
22660
22661         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22662                 error "mkdir failed"
22663         $LFS getdirstripe $DIR/$tdir
22664         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22665         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22666                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22667         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22668         [ $stripe_count -eq 2 ] ||
22669                 error "expect 2 get $stripe_count"
22670 }
22671 run_test 412 "mkdir on specific MDTs"
22672
22673 test_qos_mkdir() {
22674         local mkdir_cmd=$1
22675         local stripe_count=$2
22676         local mdts=$(comma_list $(mdts_nodes))
22677
22678         local testdir
22679         local lmv_qos_prio_free
22680         local lmv_qos_threshold_rr
22681         local lmv_qos_maxage
22682         local lod_qos_prio_free
22683         local lod_qos_threshold_rr
22684         local lod_qos_maxage
22685         local count
22686         local i
22687
22688         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22689         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22690         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22691                 head -n1)
22692         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22693         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22694         stack_trap "$LCTL set_param \
22695                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22696         stack_trap "$LCTL set_param \
22697                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22698         stack_trap "$LCTL set_param \
22699                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22700
22701         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22702                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22703         lod_qos_prio_free=${lod_qos_prio_free%%%}
22704         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22705                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22706         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22707         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22708                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22709         stack_trap "do_nodes $mdts $LCTL set_param \
22710                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22711         stack_trap "do_nodes $mdts $LCTL set_param \
22712                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22713                 EXIT
22714         stack_trap "do_nodes $mdts $LCTL set_param \
22715                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22716
22717         echo
22718         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22719
22720         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22721         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22722
22723         testdir=$DIR/$tdir-s$stripe_count/rr
22724
22725         for i in $(seq $((100 * MDSCOUNT))); do
22726                 eval $mkdir_cmd $testdir/subdir$i ||
22727                         error "$mkdir_cmd subdir$i failed"
22728         done
22729
22730         for i in $(seq $MDSCOUNT); do
22731                 count=$($LFS getdirstripe -i $testdir/* |
22732                                 grep ^$((i - 1))$ | wc -l)
22733                 echo "$count directories created on MDT$((i - 1))"
22734                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22735
22736                 if [ $stripe_count -gt 1 ]; then
22737                         count=$($LFS getdirstripe $testdir/* |
22738                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22739                         echo "$count stripes created on MDT$((i - 1))"
22740                         # deviation should < 5% of average
22741                         [ $count -lt $((95 * stripe_count)) ] ||
22742                         [ $count -gt $((105 * stripe_count)) ] &&
22743                                 error "stripes are not evenly distributed"
22744                 fi
22745         done
22746
22747         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22748         do_nodes $mdts $LCTL set_param \
22749                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22750
22751         echo
22752         echo "Check for uneven MDTs: "
22753
22754         local ffree
22755         local bavail
22756         local max
22757         local min
22758         local max_index
22759         local min_index
22760         local tmp
22761
22762         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22763         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22764         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22765
22766         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22767         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22768         max_index=0
22769         min_index=0
22770         for ((i = 1; i < ${#ffree[@]}; i++)); do
22771                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22772                 if [ $tmp -gt $max ]; then
22773                         max=$tmp
22774                         max_index=$i
22775                 fi
22776                 if [ $tmp -lt $min ]; then
22777                         min=$tmp
22778                         min_index=$i
22779                 fi
22780         done
22781
22782         [ ${ffree[min_index]} -eq 0 ] &&
22783                 skip "no free files in MDT$min_index"
22784         [ ${ffree[min_index]} -gt 100000000 ] &&
22785                 skip "too much free files in MDT$min_index"
22786
22787         # Check if we need to generate uneven MDTs
22788         local threshold=50
22789         local diff=$(((max - min) * 100 / min))
22790         local value="$(generate_string 1024)"
22791
22792         while [ $diff -lt $threshold ]; do
22793                 # generate uneven MDTs, create till $threshold% diff
22794                 echo -n "weight diff=$diff% must be > $threshold% ..."
22795                 count=$((${ffree[min_index]} / 10))
22796                 # 50 sec per 10000 files in vm
22797                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22798                         skip "$count files to create"
22799                 echo "Fill MDT$min_index with $count files"
22800                 [ -d $DIR/$tdir-MDT$min_index ] ||
22801                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22802                         error "mkdir $tdir-MDT$min_index failed"
22803                 for i in $(seq $count); do
22804                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22805                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22806                                 error "create f$j_$i failed"
22807                         setfattr -n user.413b -v $value \
22808                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22809                                 error "setfattr f$j_$i failed"
22810                 done
22811
22812                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22813                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22814                 max=$(((${ffree[max_index]} >> 8) * \
22815                         (${bavail[max_index]} * bsize >> 16)))
22816                 min=$(((${ffree[min_index]} >> 8) * \
22817                         (${bavail[min_index]} * bsize >> 16)))
22818                 diff=$(((max - min) * 100 / min))
22819         done
22820
22821         echo "MDT filesfree available: ${ffree[@]}"
22822         echo "MDT blocks available: ${bavail[@]}"
22823         echo "weight diff=$diff%"
22824
22825         echo
22826         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22827
22828         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22829         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22830         # decrease statfs age, so that it can be updated in time
22831         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22832         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22833
22834         sleep 1
22835
22836         testdir=$DIR/$tdir-s$stripe_count/qos
22837
22838         for i in $(seq $((100 * MDSCOUNT))); do
22839                 eval $mkdir_cmd $testdir/subdir$i ||
22840                         error "$mkdir_cmd subdir$i failed"
22841         done
22842
22843         for i in $(seq $MDSCOUNT); do
22844                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22845                         wc -l)
22846                 echo "$count directories created on MDT$((i - 1))"
22847
22848                 if [ $stripe_count -gt 1 ]; then
22849                         count=$($LFS getdirstripe $testdir/* |
22850                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22851                         echo "$count stripes created on MDT$((i - 1))"
22852                 fi
22853         done
22854
22855         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22856         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22857
22858         # D-value should > 10% of averge
22859         [ $((max - min)) -lt 10 ] &&
22860                 error "subdirs shouldn't be evenly distributed"
22861
22862         # ditto
22863         if [ $stripe_count -gt 1 ]; then
22864                 max=$($LFS getdirstripe $testdir/* |
22865                         grep -P "^\s+$max_index\t" | wc -l)
22866                 min=$($LFS getdirstripe $testdir/* |
22867                         grep -P "^\s+$min_index\t" | wc -l)
22868                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22869                         error "stripes shouldn't be evenly distributed"|| true
22870         fi
22871 }
22872
22873 test_413a() {
22874         [ $MDSCOUNT -lt 2 ] &&
22875                 skip "We need at least 2 MDTs for this test"
22876
22877         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22878                 skip "Need server version at least 2.12.52"
22879
22880         local stripe_count
22881
22882         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22883                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22884                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22885                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22886                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22887         done
22888 }
22889 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22890
22891 test_413b() {
22892         [ $MDSCOUNT -lt 2 ] &&
22893                 skip "We need at least 2 MDTs for this test"
22894
22895         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22896                 skip "Need server version at least 2.12.52"
22897
22898         local stripe_count
22899
22900         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22901                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22902                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22903                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22904                 $LFS setdirstripe -D -c $stripe_count \
22905                         $DIR/$tdir-s$stripe_count/rr ||
22906                         error "setdirstripe failed"
22907                 $LFS setdirstripe -D -c $stripe_count \
22908                         $DIR/$tdir-s$stripe_count/qos ||
22909                         error "setdirstripe failed"
22910                 test_qos_mkdir "mkdir" $stripe_count
22911         done
22912 }
22913 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22914
22915 test_414() {
22916 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22917         $LCTL set_param fail_loc=0x80000521
22918         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22919         rm -f $DIR/$tfile
22920 }
22921 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22922
22923 test_415() {
22924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22925         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22926                 skip "Need server version at least 2.11.52"
22927
22928         # LU-11102
22929         local total
22930         local setattr_pid
22931         local start_time
22932         local end_time
22933         local duration
22934
22935         total=500
22936         # this test may be slow on ZFS
22937         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22938
22939         # though this test is designed for striped directory, let's test normal
22940         # directory too since lock is always saved as CoS lock.
22941         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22942         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22943
22944         (
22945                 while true; do
22946                         touch $DIR/$tdir
22947                 done
22948         ) &
22949         setattr_pid=$!
22950
22951         start_time=$(date +%s)
22952         for i in $(seq $total); do
22953                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22954                         > /dev/null
22955         done
22956         end_time=$(date +%s)
22957         duration=$((end_time - start_time))
22958
22959         kill -9 $setattr_pid
22960
22961         echo "rename $total files took $duration sec"
22962         [ $duration -lt 100 ] || error "rename took $duration sec"
22963 }
22964 run_test 415 "lock revoke is not missing"
22965
22966 test_416() {
22967         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22968                 skip "Need server version at least 2.11.55"
22969
22970         # define OBD_FAIL_OSD_TXN_START    0x19a
22971         do_facet mds1 lctl set_param fail_loc=0x19a
22972
22973         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22974
22975         true
22976 }
22977 run_test 416 "transaction start failure won't cause system hung"
22978
22979 cleanup_417() {
22980         trap 0
22981         do_nodes $(comma_list $(mdts_nodes)) \
22982                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22983         do_nodes $(comma_list $(mdts_nodes)) \
22984                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22985         do_nodes $(comma_list $(mdts_nodes)) \
22986                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22987 }
22988
22989 test_417() {
22990         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22991         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22992                 skip "Need MDS version at least 2.11.56"
22993
22994         trap cleanup_417 RETURN EXIT
22995
22996         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22997         do_nodes $(comma_list $(mdts_nodes)) \
22998                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22999         $LFS migrate -m 0 $DIR/$tdir.1 &&
23000                 error "migrate dir $tdir.1 should fail"
23001
23002         do_nodes $(comma_list $(mdts_nodes)) \
23003                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23004         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23005                 error "create remote dir $tdir.2 should fail"
23006
23007         do_nodes $(comma_list $(mdts_nodes)) \
23008                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23009         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23010                 error "create striped dir $tdir.3 should fail"
23011         true
23012 }
23013 run_test 417 "disable remote dir, striped dir and dir migration"
23014
23015 # Checks that the outputs of df [-i] and lfs df [-i] match
23016 #
23017 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23018 check_lfs_df() {
23019         local dir=$2
23020         local inodes
23021         local df_out
23022         local lfs_df_out
23023         local count
23024         local passed=false
23025
23026         # blocks or inodes
23027         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23028
23029         for count in {1..100}; do
23030                 cancel_lru_locks
23031                 sync; sleep 0.2
23032
23033                 # read the lines of interest
23034                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23035                         error "df $inodes $dir | tail -n +2 failed"
23036                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23037                         error "lfs df $inodes $dir | grep summary: failed"
23038
23039                 # skip first substrings of each output as they are different
23040                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23041                 # compare the two outputs
23042                 passed=true
23043                 for i in {1..5}; do
23044                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23045                 done
23046                 $passed && break
23047         done
23048
23049         if ! $passed; then
23050                 df -P $inodes $dir
23051                 echo
23052                 lfs df $inodes $dir
23053                 error "df and lfs df $1 output mismatch: "      \
23054                       "df ${inodes}: ${df_out[*]}, "            \
23055                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23056         fi
23057 }
23058
23059 test_418() {
23060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23061
23062         local dir=$DIR/$tdir
23063         local numfiles=$((RANDOM % 4096 + 2))
23064         local numblocks=$((RANDOM % 256 + 1))
23065
23066         wait_delete_completed
23067         test_mkdir $dir
23068
23069         # check block output
23070         check_lfs_df blocks $dir
23071         # check inode output
23072         check_lfs_df inodes $dir
23073
23074         # create a single file and retest
23075         echo "Creating a single file and testing"
23076         createmany -o $dir/$tfile- 1 &>/dev/null ||
23077                 error "creating 1 file in $dir failed"
23078         check_lfs_df blocks $dir
23079         check_lfs_df inodes $dir
23080
23081         # create a random number of files
23082         echo "Creating $((numfiles - 1)) files and testing"
23083         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23084                 error "creating $((numfiles - 1)) files in $dir failed"
23085
23086         # write a random number of blocks to the first test file
23087         echo "Writing $numblocks 4K blocks and testing"
23088         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23089                 count=$numblocks &>/dev/null ||
23090                 error "dd to $dir/${tfile}-0 failed"
23091
23092         # retest
23093         check_lfs_df blocks $dir
23094         check_lfs_df inodes $dir
23095
23096         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23097                 error "unlinking $numfiles files in $dir failed"
23098 }
23099 run_test 418 "df and lfs df outputs match"
23100
23101 test_419()
23102 {
23103         local dir=$DIR/$tdir
23104
23105         mkdir -p $dir
23106         touch $dir/file
23107
23108         cancel_lru_locks mdc
23109
23110         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23111         $LCTL set_param fail_loc=0x1410
23112         cat $dir/file
23113         $LCTL set_param fail_loc=0
23114         rm -rf $dir
23115 }
23116 run_test 419 "Verify open file by name doesn't crash kernel"
23117
23118 test_420()
23119 {
23120         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23121                 skip "Need MDS version at least 2.12.53"
23122
23123         local SAVE_UMASK=$(umask)
23124         local dir=$DIR/$tdir
23125         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23126
23127         mkdir -p $dir
23128         umask 0000
23129         mkdir -m03777 $dir/testdir
23130         ls -dn $dir/testdir
23131         # Need to remove trailing '.' when SELinux is enabled
23132         local dirperms=$(ls -dn $dir/testdir |
23133                          awk '{ sub(/\.$/, "", $1); print $1}')
23134         [ $dirperms == "drwxrwsrwt" ] ||
23135                 error "incorrect perms on $dir/testdir"
23136
23137         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23138                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23139         ls -n $dir/testdir/testfile
23140         local fileperms=$(ls -n $dir/testdir/testfile |
23141                           awk '{ sub(/\.$/, "", $1); print $1}')
23142         [ $fileperms == "-rwxr-xr-x" ] ||
23143                 error "incorrect perms on $dir/testdir/testfile"
23144
23145         umask $SAVE_UMASK
23146 }
23147 run_test 420 "clear SGID bit on non-directories for non-members"
23148
23149 test_421a() {
23150         local cnt
23151         local fid1
23152         local fid2
23153
23154         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23155                 skip "Need MDS version at least 2.12.54"
23156
23157         test_mkdir $DIR/$tdir
23158         createmany -o $DIR/$tdir/f 3
23159         cnt=$(ls -1 $DIR/$tdir | wc -l)
23160         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23161
23162         fid1=$(lfs path2fid $DIR/$tdir/f1)
23163         fid2=$(lfs path2fid $DIR/$tdir/f2)
23164         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23165
23166         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23167         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23168
23169         cnt=$(ls -1 $DIR/$tdir | wc -l)
23170         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23171
23172         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23173         createmany -o $DIR/$tdir/f 3
23174         cnt=$(ls -1 $DIR/$tdir | wc -l)
23175         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23176
23177         fid1=$(lfs path2fid $DIR/$tdir/f1)
23178         fid2=$(lfs path2fid $DIR/$tdir/f2)
23179         echo "remove using fsname $FSNAME"
23180         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23181
23182         cnt=$(ls -1 $DIR/$tdir | wc -l)
23183         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23184 }
23185 run_test 421a "simple rm by fid"
23186
23187 test_421b() {
23188         local cnt
23189         local FID1
23190         local FID2
23191
23192         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23193                 skip "Need MDS version at least 2.12.54"
23194
23195         test_mkdir $DIR/$tdir
23196         createmany -o $DIR/$tdir/f 3
23197         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23198         MULTIPID=$!
23199
23200         FID1=$(lfs path2fid $DIR/$tdir/f1)
23201         FID2=$(lfs path2fid $DIR/$tdir/f2)
23202         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23203
23204         kill -USR1 $MULTIPID
23205         wait
23206
23207         cnt=$(ls $DIR/$tdir | wc -l)
23208         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23209 }
23210 run_test 421b "rm by fid on open file"
23211
23212 test_421c() {
23213         local cnt
23214         local FIDS
23215
23216         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23217                 skip "Need MDS version at least 2.12.54"
23218
23219         test_mkdir $DIR/$tdir
23220         createmany -o $DIR/$tdir/f 3
23221         touch $DIR/$tdir/$tfile
23222         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23223         cnt=$(ls -1 $DIR/$tdir | wc -l)
23224         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23225
23226         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23227         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23228
23229         cnt=$(ls $DIR/$tdir | wc -l)
23230         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23231 }
23232 run_test 421c "rm by fid against hardlinked files"
23233
23234 test_421d() {
23235         local cnt
23236         local FIDS
23237
23238         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23239                 skip "Need MDS version at least 2.12.54"
23240
23241         test_mkdir $DIR/$tdir
23242         createmany -o $DIR/$tdir/f 4097
23243         cnt=$(ls -1 $DIR/$tdir | wc -l)
23244         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23245
23246         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23247         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23248
23249         cnt=$(ls $DIR/$tdir | wc -l)
23250         rm -rf $DIR/$tdir
23251         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23252 }
23253 run_test 421d "rmfid en masse"
23254
23255 test_421e() {
23256         local cnt
23257         local FID
23258
23259         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23260         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23261                 skip "Need MDS version at least 2.12.54"
23262
23263         mkdir -p $DIR/$tdir
23264         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23265         createmany -o $DIR/$tdir/striped_dir/f 512
23266         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23267         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23268
23269         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23270                 sed "s/[/][^:]*://g")
23271         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23272
23273         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23274         rm -rf $DIR/$tdir
23275         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23276 }
23277 run_test 421e "rmfid in DNE"
23278
23279 test_421f() {
23280         local cnt
23281         local FID
23282
23283         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23284                 skip "Need MDS version at least 2.12.54"
23285
23286         test_mkdir $DIR/$tdir
23287         touch $DIR/$tdir/f
23288         cnt=$(ls -1 $DIR/$tdir | wc -l)
23289         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23290
23291         FID=$(lfs path2fid $DIR/$tdir/f)
23292         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23293         # rmfid should fail
23294         cnt=$(ls -1 $DIR/$tdir | wc -l)
23295         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23296
23297         chmod a+rw $DIR/$tdir
23298         ls -la $DIR/$tdir
23299         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23300         # rmfid should fail
23301         cnt=$(ls -1 $DIR/$tdir | wc -l)
23302         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23303
23304         rm -f $DIR/$tdir/f
23305         $RUNAS touch $DIR/$tdir/f
23306         FID=$(lfs path2fid $DIR/$tdir/f)
23307         echo "rmfid as root"
23308         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23309         cnt=$(ls -1 $DIR/$tdir | wc -l)
23310         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23311
23312         rm -f $DIR/$tdir/f
23313         $RUNAS touch $DIR/$tdir/f
23314         cnt=$(ls -1 $DIR/$tdir | wc -l)
23315         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23316         FID=$(lfs path2fid $DIR/$tdir/f)
23317         # rmfid w/o user_fid2path mount option should fail
23318         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23319         cnt=$(ls -1 $DIR/$tdir | wc -l)
23320         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23321
23322         umount_client $MOUNT || error "failed to umount client"
23323         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23324                 error "failed to mount client'"
23325
23326         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23327         # rmfid should succeed
23328         cnt=$(ls -1 $DIR/$tdir | wc -l)
23329         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23330
23331         # rmfid shouldn't allow to remove files due to dir's permission
23332         chmod a+rwx $DIR/$tdir
23333         touch $DIR/$tdir/f
23334         ls -la $DIR/$tdir
23335         FID=$(lfs path2fid $DIR/$tdir/f)
23336         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23337
23338         umount_client $MOUNT || error "failed to umount client"
23339         mount_client $MOUNT "$MOUNT_OPTS" ||
23340                 error "failed to mount client'"
23341
23342 }
23343 run_test 421f "rmfid checks permissions"
23344
23345 test_421g() {
23346         local cnt
23347         local FIDS
23348
23349         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23350         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23351                 skip "Need MDS version at least 2.12.54"
23352
23353         mkdir -p $DIR/$tdir
23354         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23355         createmany -o $DIR/$tdir/striped_dir/f 512
23356         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23357         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23358
23359         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23360                 sed "s/[/][^:]*://g")
23361
23362         rm -f $DIR/$tdir/striped_dir/f1*
23363         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23364         removed=$((512 - cnt))
23365
23366         # few files have been just removed, so we expect
23367         # rmfid to fail on their fids
23368         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23369         [ $removed != $errors ] && error "$errors != $removed"
23370
23371         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23372         rm -rf $DIR/$tdir
23373         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23374 }
23375 run_test 421g "rmfid to return errors properly"
23376
23377 test_422() {
23378         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23379         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23380         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23381         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23382         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23383
23384         local amc=$(at_max_get client)
23385         local amo=$(at_max_get mds1)
23386         local timeout=`lctl get_param -n timeout`
23387
23388         at_max_set 0 client
23389         at_max_set 0 mds1
23390
23391 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23392         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23393                         fail_val=$(((2*timeout + 10)*1000))
23394         touch $DIR/$tdir/d3/file &
23395         sleep 2
23396 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23397         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23398                         fail_val=$((2*timeout + 5))
23399         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23400         local pid=$!
23401         sleep 1
23402         kill -9 $pid
23403         sleep $((2 * timeout))
23404         echo kill $pid
23405         kill -9 $pid
23406         lctl mark touch
23407         touch $DIR/$tdir/d2/file3
23408         touch $DIR/$tdir/d2/file4
23409         touch $DIR/$tdir/d2/file5
23410
23411         wait
23412         at_max_set $amc client
23413         at_max_set $amo mds1
23414
23415         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23416         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23417                 error "Watchdog is always throttled"
23418 }
23419 run_test 422 "kill a process with RPC in progress"
23420
23421 stat_test() {
23422     df -h $MOUNT &
23423     df -h $MOUNT &
23424     df -h $MOUNT &
23425     df -h $MOUNT &
23426     df -h $MOUNT &
23427     df -h $MOUNT &
23428 }
23429
23430 test_423() {
23431     local _stats
23432     # ensure statfs cache is expired
23433     sleep 2;
23434
23435     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23436     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23437
23438     return 0
23439 }
23440 run_test 423 "statfs should return a right data"
23441
23442 test_424() {
23443 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23444         $LCTL set_param fail_loc=0x80000522
23445         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23446         rm -f $DIR/$tfile
23447 }
23448 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23449
23450 test_425() {
23451         test_mkdir -c -1 $DIR/$tdir
23452         $LFS setstripe -c -1 $DIR/$tdir
23453
23454         lru_resize_disable "" 100
23455         stack_trap "lru_resize_enable" EXIT
23456
23457         sleep 5
23458
23459         for i in $(seq $((MDSCOUNT * 125))); do
23460                 local t=$DIR/$tdir/$tfile_$i
23461
23462                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23463                         error_noexit "Create file $t"
23464         done
23465         stack_trap "rm -rf $DIR/$tdir" EXIT
23466
23467         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23468                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23469                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23470
23471                 [ $lock_count -le $lru_size ] ||
23472                         error "osc lock count $lock_count > lru size $lru_size"
23473         done
23474
23475         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23476                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23477                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23478
23479                 [ $lock_count -le $lru_size ] ||
23480                         error "mdc lock count $lock_count > lru size $lru_size"
23481         done
23482 }
23483 run_test 425 "lock count should not exceed lru size"
23484
23485 test_426() {
23486         splice-test -r $DIR/$tfile
23487         splice-test -rd $DIR/$tfile
23488         splice-test $DIR/$tfile
23489         splice-test -d $DIR/$tfile
23490 }
23491 run_test 426 "splice test on Lustre"
23492
23493 prep_801() {
23494         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23495         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23496                 skip "Need server version at least 2.9.55"
23497
23498         start_full_debug_logging
23499 }
23500
23501 post_801() {
23502         stop_full_debug_logging
23503 }
23504
23505 barrier_stat() {
23506         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23507                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23508                            awk '/The barrier for/ { print $7 }')
23509                 echo $st
23510         else
23511                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23512                 echo \'$st\'
23513         fi
23514 }
23515
23516 barrier_expired() {
23517         local expired
23518
23519         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23520                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23521                           awk '/will be expired/ { print $7 }')
23522         else
23523                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23524         fi
23525
23526         echo $expired
23527 }
23528
23529 test_801a() {
23530         prep_801
23531
23532         echo "Start barrier_freeze at: $(date)"
23533         #define OBD_FAIL_BARRIER_DELAY          0x2202
23534         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23535         # Do not reduce barrier time - See LU-11873
23536         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23537
23538         sleep 2
23539         local b_status=$(barrier_stat)
23540         echo "Got barrier status at: $(date)"
23541         [ "$b_status" = "'freezing_p1'" ] ||
23542                 error "(1) unexpected barrier status $b_status"
23543
23544         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23545         wait
23546         b_status=$(barrier_stat)
23547         [ "$b_status" = "'frozen'" ] ||
23548                 error "(2) unexpected barrier status $b_status"
23549
23550         local expired=$(barrier_expired)
23551         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23552         sleep $((expired + 3))
23553
23554         b_status=$(barrier_stat)
23555         [ "$b_status" = "'expired'" ] ||
23556                 error "(3) unexpected barrier status $b_status"
23557
23558         # Do not reduce barrier time - See LU-11873
23559         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23560                 error "(4) fail to freeze barrier"
23561
23562         b_status=$(barrier_stat)
23563         [ "$b_status" = "'frozen'" ] ||
23564                 error "(5) unexpected barrier status $b_status"
23565
23566         echo "Start barrier_thaw at: $(date)"
23567         #define OBD_FAIL_BARRIER_DELAY          0x2202
23568         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23569         do_facet mgs $LCTL barrier_thaw $FSNAME &
23570
23571         sleep 2
23572         b_status=$(barrier_stat)
23573         echo "Got barrier status at: $(date)"
23574         [ "$b_status" = "'thawing'" ] ||
23575                 error "(6) unexpected barrier status $b_status"
23576
23577         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23578         wait
23579         b_status=$(barrier_stat)
23580         [ "$b_status" = "'thawed'" ] ||
23581                 error "(7) unexpected barrier status $b_status"
23582
23583         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23584         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23585         do_facet mgs $LCTL barrier_freeze $FSNAME
23586
23587         b_status=$(barrier_stat)
23588         [ "$b_status" = "'failed'" ] ||
23589                 error "(8) unexpected barrier status $b_status"
23590
23591         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23592         do_facet mgs $LCTL barrier_thaw $FSNAME
23593
23594         post_801
23595 }
23596 run_test 801a "write barrier user interfaces and stat machine"
23597
23598 test_801b() {
23599         prep_801
23600
23601         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23602         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23603         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23604         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23605         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23606
23607         cancel_lru_locks mdc
23608
23609         # 180 seconds should be long enough
23610         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23611
23612         local b_status=$(barrier_stat)
23613         [ "$b_status" = "'frozen'" ] ||
23614                 error "(6) unexpected barrier status $b_status"
23615
23616         mkdir $DIR/$tdir/d0/d10 &
23617         mkdir_pid=$!
23618
23619         touch $DIR/$tdir/d1/f13 &
23620         touch_pid=$!
23621
23622         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23623         ln_pid=$!
23624
23625         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23626         mv_pid=$!
23627
23628         rm -f $DIR/$tdir/d4/f12 &
23629         rm_pid=$!
23630
23631         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23632
23633         # To guarantee taht the 'stat' is not blocked
23634         b_status=$(barrier_stat)
23635         [ "$b_status" = "'frozen'" ] ||
23636                 error "(8) unexpected barrier status $b_status"
23637
23638         # let above commands to run at background
23639         sleep 5
23640
23641         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23642         ps -p $touch_pid || error "(10) touch should be blocked"
23643         ps -p $ln_pid || error "(11) link should be blocked"
23644         ps -p $mv_pid || error "(12) rename should be blocked"
23645         ps -p $rm_pid || error "(13) unlink should be blocked"
23646
23647         b_status=$(barrier_stat)
23648         [ "$b_status" = "'frozen'" ] ||
23649                 error "(14) unexpected barrier status $b_status"
23650
23651         do_facet mgs $LCTL barrier_thaw $FSNAME
23652         b_status=$(barrier_stat)
23653         [ "$b_status" = "'thawed'" ] ||
23654                 error "(15) unexpected barrier status $b_status"
23655
23656         wait $mkdir_pid || error "(16) mkdir should succeed"
23657         wait $touch_pid || error "(17) touch should succeed"
23658         wait $ln_pid || error "(18) link should succeed"
23659         wait $mv_pid || error "(19) rename should succeed"
23660         wait $rm_pid || error "(20) unlink should succeed"
23661
23662         post_801
23663 }
23664 run_test 801b "modification will be blocked by write barrier"
23665
23666 test_801c() {
23667         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23668
23669         prep_801
23670
23671         stop mds2 || error "(1) Fail to stop mds2"
23672
23673         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23674
23675         local b_status=$(barrier_stat)
23676         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23677                 do_facet mgs $LCTL barrier_thaw $FSNAME
23678                 error "(2) unexpected barrier status $b_status"
23679         }
23680
23681         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23682                 error "(3) Fail to rescan barrier bitmap"
23683
23684         # Do not reduce barrier time - See LU-11873
23685         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23686
23687         b_status=$(barrier_stat)
23688         [ "$b_status" = "'frozen'" ] ||
23689                 error "(4) unexpected barrier status $b_status"
23690
23691         do_facet mgs $LCTL barrier_thaw $FSNAME
23692         b_status=$(barrier_stat)
23693         [ "$b_status" = "'thawed'" ] ||
23694                 error "(5) unexpected barrier status $b_status"
23695
23696         local devname=$(mdsdevname 2)
23697
23698         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23699
23700         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23701                 error "(7) Fail to rescan barrier bitmap"
23702
23703         post_801
23704 }
23705 run_test 801c "rescan barrier bitmap"
23706
23707 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23708 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23709 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23710 saved_MOUNT_OPTS=$MOUNT_OPTS
23711
23712 cleanup_802a() {
23713         trap 0
23714
23715         stopall
23716         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23717         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23718         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23719         MOUNT_OPTS=$saved_MOUNT_OPTS
23720         setupall
23721 }
23722
23723 test_802a() {
23724         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23725         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23726         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23727                 skip "Need server version at least 2.9.55"
23728
23729         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23730
23731         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23732
23733         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23734                 error "(2) Fail to copy"
23735
23736         trap cleanup_802a EXIT
23737
23738         # sync by force before remount as readonly
23739         sync; sync_all_data; sleep 3; sync_all_data
23740
23741         stopall
23742
23743         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23744         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23745         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23746
23747         echo "Mount the server as read only"
23748         setupall server_only || error "(3) Fail to start servers"
23749
23750         echo "Mount client without ro should fail"
23751         mount_client $MOUNT &&
23752                 error "(4) Mount client without 'ro' should fail"
23753
23754         echo "Mount client with ro should succeed"
23755         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23756         mount_client $MOUNT ||
23757                 error "(5) Mount client with 'ro' should succeed"
23758
23759         echo "Modify should be refused"
23760         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23761
23762         echo "Read should be allowed"
23763         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23764                 error "(7) Read should succeed under ro mode"
23765
23766         cleanup_802a
23767 }
23768 run_test 802a "simulate readonly device"
23769
23770 test_802b() {
23771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23772         remote_mds_nodsh && skip "remote MDS with nodsh"
23773
23774         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23775                 skip "readonly option not available"
23776
23777         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23778
23779         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23780                 error "(2) Fail to copy"
23781
23782         # write back all cached data before setting MDT to readonly
23783         cancel_lru_locks
23784         sync_all_data
23785
23786         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23787         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23788
23789         echo "Modify should be refused"
23790         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23791
23792         echo "Read should be allowed"
23793         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23794                 error "(7) Read should succeed under ro mode"
23795
23796         # disable readonly
23797         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23798 }
23799 run_test 802b "be able to set MDTs to readonly"
23800
23801 test_803() {
23802         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23803         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23804                 skip "MDS needs to be newer than 2.10.54"
23805
23806         mkdir -p $DIR/$tdir
23807         # Create some objects on all MDTs to trigger related logs objects
23808         for idx in $(seq $MDSCOUNT); do
23809                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23810                         $DIR/$tdir/dir${idx} ||
23811                         error "Fail to create $DIR/$tdir/dir${idx}"
23812         done
23813
23814         sync; sleep 3
23815         wait_delete_completed # ensure old test cleanups are finished
23816         echo "before create:"
23817         $LFS df -i $MOUNT
23818         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23819
23820         for i in {1..10}; do
23821                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23822                         error "Fail to create $DIR/$tdir/foo$i"
23823         done
23824
23825         sync; sleep 3
23826         echo "after create:"
23827         $LFS df -i $MOUNT
23828         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23829
23830         # allow for an llog to be cleaned up during the test
23831         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23832                 error "before ($before_used) + 10 > after ($after_used)"
23833
23834         for i in {1..10}; do
23835                 rm -rf $DIR/$tdir/foo$i ||
23836                         error "Fail to remove $DIR/$tdir/foo$i"
23837         done
23838
23839         sleep 3 # avoid MDT return cached statfs
23840         wait_delete_completed
23841         echo "after unlink:"
23842         $LFS df -i $MOUNT
23843         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23844
23845         # allow for an llog to be created during the test
23846         [ $after_used -le $((before_used + 1)) ] ||
23847                 error "after ($after_used) > before ($before_used) + 1"
23848 }
23849 run_test 803 "verify agent object for remote object"
23850
23851 test_804() {
23852         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23853         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23854                 skip "MDS needs to be newer than 2.10.54"
23855         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23856
23857         mkdir -p $DIR/$tdir
23858         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23859                 error "Fail to create $DIR/$tdir/dir0"
23860
23861         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23862         local dev=$(mdsdevname 2)
23863
23864         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23865                 grep ${fid} || error "NOT found agent entry for dir0"
23866
23867         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23868                 error "Fail to create $DIR/$tdir/dir1"
23869
23870         touch $DIR/$tdir/dir1/foo0 ||
23871                 error "Fail to create $DIR/$tdir/dir1/foo0"
23872         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23873         local rc=0
23874
23875         for idx in $(seq $MDSCOUNT); do
23876                 dev=$(mdsdevname $idx)
23877                 do_facet mds${idx} \
23878                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23879                         grep ${fid} && rc=$idx
23880         done
23881
23882         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23883                 error "Fail to rename foo0 to foo1"
23884         if [ $rc -eq 0 ]; then
23885                 for idx in $(seq $MDSCOUNT); do
23886                         dev=$(mdsdevname $idx)
23887                         do_facet mds${idx} \
23888                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23889                         grep ${fid} && rc=$idx
23890                 done
23891         fi
23892
23893         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23894                 error "Fail to rename foo1 to foo2"
23895         if [ $rc -eq 0 ]; then
23896                 for idx in $(seq $MDSCOUNT); do
23897                         dev=$(mdsdevname $idx)
23898                         do_facet mds${idx} \
23899                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23900                         grep ${fid} && rc=$idx
23901                 done
23902         fi
23903
23904         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23905
23906         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23907                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23908         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23909                 error "Fail to rename foo2 to foo0"
23910         unlink $DIR/$tdir/dir1/foo0 ||
23911                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23912         rm -rf $DIR/$tdir/dir0 ||
23913                 error "Fail to rm $DIR/$tdir/dir0"
23914
23915         for idx in $(seq $MDSCOUNT); do
23916                 dev=$(mdsdevname $idx)
23917                 rc=0
23918
23919                 stop mds${idx}
23920                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23921                         rc=$?
23922                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23923                         error "mount mds$idx failed"
23924                 df $MOUNT > /dev/null 2>&1
23925
23926                 # e2fsck should not return error
23927                 [ $rc -eq 0 ] ||
23928                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23929         done
23930 }
23931 run_test 804 "verify agent entry for remote entry"
23932
23933 cleanup_805() {
23934         do_facet $SINGLEMDS zfs set quota=$old $fsset
23935         unlinkmany $DIR/$tdir/f- 1000000
23936         trap 0
23937 }
23938
23939 test_805() {
23940         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23941         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23942         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23943                 skip "netfree not implemented before 0.7"
23944         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23945                 skip "Need MDS version at least 2.10.57"
23946
23947         local fsset
23948         local freekb
23949         local usedkb
23950         local old
23951         local quota
23952         local pref="osd-zfs.$FSNAME-MDT0000."
23953
23954         # limit available space on MDS dataset to meet nospace issue
23955         # quickly. then ZFS 0.7.2 can use reserved space if asked
23956         # properly (using netfree flag in osd_declare_destroy()
23957         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23958         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23959                 gawk '{print $3}')
23960         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23961         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23962         let "usedkb=usedkb-freekb"
23963         let "freekb=freekb/2"
23964         if let "freekb > 5000"; then
23965                 let "freekb=5000"
23966         fi
23967         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23968         trap cleanup_805 EXIT
23969         mkdir $DIR/$tdir
23970         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23971                 error "Can't set PFL layout"
23972         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23973         rm -rf $DIR/$tdir || error "not able to remove"
23974         do_facet $SINGLEMDS zfs set quota=$old $fsset
23975         trap 0
23976 }
23977 run_test 805 "ZFS can remove from full fs"
23978
23979 # Size-on-MDS test
23980 check_lsom_data()
23981 {
23982         local file=$1
23983         local size=$($LFS getsom -s $file)
23984         local expect=$(stat -c %s $file)
23985
23986         [[ $size == $expect ]] ||
23987                 error "$file expected size: $expect, got: $size"
23988
23989         local blocks=$($LFS getsom -b $file)
23990         expect=$(stat -c %b $file)
23991         [[ $blocks == $expect ]] ||
23992                 error "$file expected blocks: $expect, got: $blocks"
23993 }
23994
23995 check_lsom_size()
23996 {
23997         local size=$($LFS getsom -s $1)
23998         local expect=$2
23999
24000         [[ $size == $expect ]] ||
24001                 error "$file expected size: $expect, got: $size"
24002 }
24003
24004 test_806() {
24005         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24006                 skip "Need MDS version at least 2.11.52"
24007
24008         local bs=1048576
24009
24010         touch $DIR/$tfile || error "touch $tfile failed"
24011
24012         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24013         save_lustre_params client "llite.*.xattr_cache" > $save
24014         lctl set_param llite.*.xattr_cache=0
24015         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24016
24017         # single-threaded write
24018         echo "Test SOM for single-threaded write"
24019         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24020                 error "write $tfile failed"
24021         check_lsom_size $DIR/$tfile $bs
24022
24023         local num=32
24024         local size=$(($num * $bs))
24025         local offset=0
24026         local i
24027
24028         echo "Test SOM for single client multi-threaded($num) write"
24029         $TRUNCATE $DIR/$tfile 0
24030         for ((i = 0; i < $num; i++)); do
24031                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24032                 local pids[$i]=$!
24033                 offset=$((offset + $bs))
24034         done
24035         for (( i=0; i < $num; i++ )); do
24036                 wait ${pids[$i]}
24037         done
24038         check_lsom_size $DIR/$tfile $size
24039
24040         $TRUNCATE $DIR/$tfile 0
24041         for ((i = 0; i < $num; i++)); do
24042                 offset=$((offset - $bs))
24043                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24044                 local pids[$i]=$!
24045         done
24046         for (( i=0; i < $num; i++ )); do
24047                 wait ${pids[$i]}
24048         done
24049         check_lsom_size $DIR/$tfile $size
24050
24051         # multi-client writes
24052         num=$(get_node_count ${CLIENTS//,/ })
24053         size=$(($num * $bs))
24054         offset=0
24055         i=0
24056
24057         echo "Test SOM for multi-client ($num) writes"
24058         $TRUNCATE $DIR/$tfile 0
24059         for client in ${CLIENTS//,/ }; do
24060                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24061                 local pids[$i]=$!
24062                 i=$((i + 1))
24063                 offset=$((offset + $bs))
24064         done
24065         for (( i=0; i < $num; i++ )); do
24066                 wait ${pids[$i]}
24067         done
24068         check_lsom_size $DIR/$tfile $offset
24069
24070         i=0
24071         $TRUNCATE $DIR/$tfile 0
24072         for client in ${CLIENTS//,/ }; do
24073                 offset=$((offset - $bs))
24074                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24075                 local pids[$i]=$!
24076                 i=$((i + 1))
24077         done
24078         for (( i=0; i < $num; i++ )); do
24079                 wait ${pids[$i]}
24080         done
24081         check_lsom_size $DIR/$tfile $size
24082
24083         # verify truncate
24084         echo "Test SOM for truncate"
24085         $TRUNCATE $DIR/$tfile 1048576
24086         check_lsom_size $DIR/$tfile 1048576
24087         $TRUNCATE $DIR/$tfile 1234
24088         check_lsom_size $DIR/$tfile 1234
24089
24090         # verify SOM blocks count
24091         echo "Verify SOM block count"
24092         $TRUNCATE $DIR/$tfile 0
24093         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24094                 error "failed to write file $tfile"
24095         check_lsom_data $DIR/$tfile
24096 }
24097 run_test 806 "Verify Lazy Size on MDS"
24098
24099 test_807() {
24100         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24101         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24102                 skip "Need MDS version at least 2.11.52"
24103
24104         # Registration step
24105         changelog_register || error "changelog_register failed"
24106         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24107         changelog_users $SINGLEMDS | grep -q $cl_user ||
24108                 error "User $cl_user not found in changelog_users"
24109
24110         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24111         save_lustre_params client "llite.*.xattr_cache" > $save
24112         lctl set_param llite.*.xattr_cache=0
24113         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24114
24115         rm -rf $DIR/$tdir || error "rm $tdir failed"
24116         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24117         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24118         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24119         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24120                 error "truncate $tdir/trunc failed"
24121
24122         local bs=1048576
24123         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24124                 error "write $tfile failed"
24125
24126         # multi-client wirtes
24127         local num=$(get_node_count ${CLIENTS//,/ })
24128         local offset=0
24129         local i=0
24130
24131         echo "Test SOM for multi-client ($num) writes"
24132         touch $DIR/$tfile || error "touch $tfile failed"
24133         $TRUNCATE $DIR/$tfile 0
24134         for client in ${CLIENTS//,/ }; do
24135                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24136                 local pids[$i]=$!
24137                 i=$((i + 1))
24138                 offset=$((offset + $bs))
24139         done
24140         for (( i=0; i < $num; i++ )); do
24141                 wait ${pids[$i]}
24142         done
24143
24144         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24145         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24146         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24147         check_lsom_data $DIR/$tdir/trunc
24148         check_lsom_data $DIR/$tdir/single_dd
24149         check_lsom_data $DIR/$tfile
24150
24151         rm -rf $DIR/$tdir
24152         # Deregistration step
24153         changelog_deregister || error "changelog_deregister failed"
24154 }
24155 run_test 807 "verify LSOM syncing tool"
24156
24157 check_som_nologged()
24158 {
24159         local lines=$($LFS changelog $FSNAME-MDT0000 |
24160                 grep 'x=trusted.som' | wc -l)
24161         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24162 }
24163
24164 test_808() {
24165         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24166                 skip "Need MDS version at least 2.11.55"
24167
24168         # Registration step
24169         changelog_register || error "changelog_register failed"
24170
24171         touch $DIR/$tfile || error "touch $tfile failed"
24172         check_som_nologged
24173
24174         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24175                 error "write $tfile failed"
24176         check_som_nologged
24177
24178         $TRUNCATE $DIR/$tfile 1234
24179         check_som_nologged
24180
24181         $TRUNCATE $DIR/$tfile 1048576
24182         check_som_nologged
24183
24184         # Deregistration step
24185         changelog_deregister || error "changelog_deregister failed"
24186 }
24187 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24188
24189 check_som_nodata()
24190 {
24191         $LFS getsom $1
24192         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24193 }
24194
24195 test_809() {
24196         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24197                 skip "Need MDS version at least 2.11.56"
24198
24199         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24200                 error "failed to create DoM-only file $DIR/$tfile"
24201         touch $DIR/$tfile || error "touch $tfile failed"
24202         check_som_nodata $DIR/$tfile
24203
24204         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24205                 error "write $tfile failed"
24206         check_som_nodata $DIR/$tfile
24207
24208         $TRUNCATE $DIR/$tfile 1234
24209         check_som_nodata $DIR/$tfile
24210
24211         $TRUNCATE $DIR/$tfile 4097
24212         check_som_nodata $DIR/$file
24213 }
24214 run_test 809 "Verify no SOM xattr store for DoM-only files"
24215
24216 test_810() {
24217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24218         $GSS && skip_env "could not run with gss"
24219         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24220                 skip "OST < 2.12.58 doesn't align checksum"
24221
24222         set_checksums 1
24223         stack_trap "set_checksums $ORIG_CSUM" EXIT
24224         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24225
24226         local csum
24227         local before
24228         local after
24229         for csum in $CKSUM_TYPES; do
24230                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24231                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24232                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24233                         eval set -- $i
24234                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24235                         before=$(md5sum $DIR/$tfile)
24236                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24237                         after=$(md5sum $DIR/$tfile)
24238                         [ "$before" == "$after" ] ||
24239                                 error "$csum: $before != $after bs=$1 seek=$2"
24240                 done
24241         done
24242 }
24243 run_test 810 "partial page writes on ZFS (LU-11663)"
24244
24245 test_812a() {
24246         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24247                 skip "OST < 2.12.51 doesn't support this fail_loc"
24248         [ "$SHARED_KEY" = true ] &&
24249                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24250
24251         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24252         # ensure ost1 is connected
24253         stat $DIR/$tfile >/dev/null || error "can't stat"
24254         wait_osc_import_state client ost1 FULL
24255         # no locks, no reqs to let the connection idle
24256         cancel_lru_locks osc
24257
24258         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24259 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24260         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24261         wait_osc_import_state client ost1 CONNECTING
24262         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24263
24264         stat $DIR/$tfile >/dev/null || error "can't stat file"
24265 }
24266 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24267
24268 test_812b() { # LU-12378
24269         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24270                 skip "OST < 2.12.51 doesn't support this fail_loc"
24271         [ "$SHARED_KEY" = true ] &&
24272                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24273
24274         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24275         # ensure ost1 is connected
24276         stat $DIR/$tfile >/dev/null || error "can't stat"
24277         wait_osc_import_state client ost1 FULL
24278         # no locks, no reqs to let the connection idle
24279         cancel_lru_locks osc
24280
24281         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24282 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24283         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24284         wait_osc_import_state client ost1 CONNECTING
24285         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24286
24287         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24288         wait_osc_import_state client ost1 IDLE
24289 }
24290 run_test 812b "do not drop no resend request for idle connect"
24291
24292 test_813() {
24293         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24294         [ -z "$file_heat_sav" ] && skip "no file heat support"
24295
24296         local readsample
24297         local writesample
24298         local readbyte
24299         local writebyte
24300         local readsample1
24301         local writesample1
24302         local readbyte1
24303         local writebyte1
24304
24305         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24306         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24307
24308         $LCTL set_param -n llite.*.file_heat=1
24309         echo "Turn on file heat"
24310         echo "Period second: $period_second, Decay percentage: $decay_pct"
24311
24312         echo "QQQQ" > $DIR/$tfile
24313         echo "QQQQ" > $DIR/$tfile
24314         echo "QQQQ" > $DIR/$tfile
24315         cat $DIR/$tfile > /dev/null
24316         cat $DIR/$tfile > /dev/null
24317         cat $DIR/$tfile > /dev/null
24318         cat $DIR/$tfile > /dev/null
24319
24320         local out=$($LFS heat_get $DIR/$tfile)
24321
24322         $LFS heat_get $DIR/$tfile
24323         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24324         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24325         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24326         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24327
24328         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24329         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24330         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24331         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24332
24333         sleep $((period_second + 3))
24334         echo "Sleep $((period_second + 3)) seconds..."
24335         # The recursion formula to calculate the heat of the file f is as
24336         # follow:
24337         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24338         # Where Hi is the heat value in the period between time points i*I and
24339         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24340         # to the weight of Ci.
24341         out=$($LFS heat_get $DIR/$tfile)
24342         $LFS heat_get $DIR/$tfile
24343         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24344         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24345         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24346         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24347
24348         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24349                 error "read sample ($readsample) is wrong"
24350         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24351                 error "write sample ($writesample) is wrong"
24352         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24353                 error "read bytes ($readbyte) is wrong"
24354         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24355                 error "write bytes ($writebyte) is wrong"
24356
24357         echo "QQQQ" > $DIR/$tfile
24358         echo "QQQQ" > $DIR/$tfile
24359         echo "QQQQ" > $DIR/$tfile
24360         cat $DIR/$tfile > /dev/null
24361         cat $DIR/$tfile > /dev/null
24362         cat $DIR/$tfile > /dev/null
24363         cat $DIR/$tfile > /dev/null
24364
24365         sleep $((period_second + 3))
24366         echo "Sleep $((period_second + 3)) seconds..."
24367
24368         out=$($LFS heat_get $DIR/$tfile)
24369         $LFS heat_get $DIR/$tfile
24370         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24371         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24372         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24373         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24374
24375         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24376                 4 * $decay_pct) / 100") -eq 1 ] ||
24377                 error "read sample ($readsample1) is wrong"
24378         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24379                 3 * $decay_pct) / 100") -eq 1 ] ||
24380                 error "write sample ($writesample1) is wrong"
24381         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24382                 20 * $decay_pct) / 100") -eq 1 ] ||
24383                 error "read bytes ($readbyte1) is wrong"
24384         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24385                 15 * $decay_pct) / 100") -eq 1 ] ||
24386                 error "write bytes ($writebyte1) is wrong"
24387
24388         echo "Turn off file heat for the file $DIR/$tfile"
24389         $LFS heat_set -o $DIR/$tfile
24390
24391         echo "QQQQ" > $DIR/$tfile
24392         echo "QQQQ" > $DIR/$tfile
24393         echo "QQQQ" > $DIR/$tfile
24394         cat $DIR/$tfile > /dev/null
24395         cat $DIR/$tfile > /dev/null
24396         cat $DIR/$tfile > /dev/null
24397         cat $DIR/$tfile > /dev/null
24398
24399         out=$($LFS heat_get $DIR/$tfile)
24400         $LFS heat_get $DIR/$tfile
24401         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24402         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24403         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24404         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24405
24406         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24407         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24408         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24409         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24410
24411         echo "Trun on file heat for the file $DIR/$tfile"
24412         $LFS heat_set -O $DIR/$tfile
24413
24414         echo "QQQQ" > $DIR/$tfile
24415         echo "QQQQ" > $DIR/$tfile
24416         echo "QQQQ" > $DIR/$tfile
24417         cat $DIR/$tfile > /dev/null
24418         cat $DIR/$tfile > /dev/null
24419         cat $DIR/$tfile > /dev/null
24420         cat $DIR/$tfile > /dev/null
24421
24422         out=$($LFS heat_get $DIR/$tfile)
24423         $LFS heat_get $DIR/$tfile
24424         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24425         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24426         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24427         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24428
24429         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24430         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24431         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24432         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24433
24434         $LFS heat_set -c $DIR/$tfile
24435         $LCTL set_param -n llite.*.file_heat=0
24436         echo "Turn off file heat support for the Lustre filesystem"
24437
24438         echo "QQQQ" > $DIR/$tfile
24439         echo "QQQQ" > $DIR/$tfile
24440         echo "QQQQ" > $DIR/$tfile
24441         cat $DIR/$tfile > /dev/null
24442         cat $DIR/$tfile > /dev/null
24443         cat $DIR/$tfile > /dev/null
24444         cat $DIR/$tfile > /dev/null
24445
24446         out=$($LFS heat_get $DIR/$tfile)
24447         $LFS heat_get $DIR/$tfile
24448         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24449         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24450         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24451         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24452
24453         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24454         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24455         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24456         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24457
24458         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24459         rm -f $DIR/$tfile
24460 }
24461 run_test 813 "File heat verfication"
24462
24463 test_814()
24464 {
24465         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24466         echo -n y >> $DIR/$tfile
24467         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24468         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24469 }
24470 run_test 814 "sparse cp works as expected (LU-12361)"
24471
24472 test_815()
24473 {
24474         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24475         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24476 }
24477 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24478
24479 test_816() {
24480         [ "$SHARED_KEY" = true ] &&
24481                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24482
24483         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24484         # ensure ost1 is connected
24485         stat $DIR/$tfile >/dev/null || error "can't stat"
24486         wait_osc_import_state client ost1 FULL
24487         # no locks, no reqs to let the connection idle
24488         cancel_lru_locks osc
24489         lru_resize_disable osc
24490         local before
24491         local now
24492         before=$($LCTL get_param -n \
24493                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24494
24495         wait_osc_import_state client ost1 IDLE
24496         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24497         now=$($LCTL get_param -n \
24498               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24499         [ $before == $now ] || error "lru_size changed $before != $now"
24500 }
24501 run_test 816 "do not reset lru_resize on idle reconnect"
24502
24503 cleanup_817() {
24504         umount $tmpdir
24505         exportfs -u localhost:$DIR/nfsexp
24506         rm -rf $DIR/nfsexp
24507 }
24508
24509 test_817() {
24510         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24511
24512         mkdir -p $DIR/nfsexp
24513         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24514                 error "failed to export nfs"
24515
24516         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24517         stack_trap cleanup_817 EXIT
24518
24519         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24520                 error "failed to mount nfs to $tmpdir"
24521
24522         cp /bin/true $tmpdir
24523         $DIR/nfsexp/true || error "failed to execute 'true' command"
24524 }
24525 run_test 817 "nfsd won't cache write lock for exec file"
24526
24527 test_818() {
24528         mkdir $DIR/$tdir
24529         $LFS setstripe -c1 -i0 $DIR/$tfile
24530         $LFS setstripe -c1 -i1 $DIR/$tfile
24531         stop $SINGLEMDS
24532         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24533         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24534         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24535                 error "start $SINGLEMDS failed"
24536         rm -rf $DIR/$tdir
24537 }
24538 run_test 818 "unlink with failed llog"
24539
24540 test_819a() {
24541         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24542         cancel_lru_locks osc
24543         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24544         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24545         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24546         rm -f $TDIR/$tfile
24547 }
24548 run_test 819a "too big niobuf in read"
24549
24550 test_819b() {
24551         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24552         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24554         cancel_lru_locks osc
24555         sleep 1
24556         rm -f $TDIR/$tfile
24557 }
24558 run_test 819b "too big niobuf in write"
24559
24560
24561 function test_820_start_ost() {
24562         sleep 5
24563
24564         for num in $(seq $OSTCOUNT); do
24565                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24566         done
24567 }
24568
24569 test_820() {
24570         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24571
24572         mkdir $DIR/$tdir
24573         umount_client $MOUNT || error "umount failed"
24574         for num in $(seq $OSTCOUNT); do
24575                 stop ost$num
24576         done
24577
24578         # mount client with no active OSTs
24579         # so that the client can't initialize max LOV EA size
24580         # from OSC notifications
24581         mount_client $MOUNT || error "mount failed"
24582         # delay OST starting to keep this 0 max EA size for a while
24583         test_820_start_ost &
24584
24585         # create a directory on MDS2
24586         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24587                 error "Failed to create directory"
24588         # open intent should update default EA size
24589         # see mdc_update_max_ea_from_body()
24590         # notice this is the very first RPC to MDS2
24591         cp /etc/services $DIR/$tdir/mds2 ||
24592                 error "Failed to copy files to mds$n"
24593 }
24594 run_test 820 "update max EA from open intent"
24595
24596 #
24597 # tests that do cleanup/setup should be run at the end
24598 #
24599
24600 test_900() {
24601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24602         local ls
24603
24604         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24605         $LCTL set_param fail_loc=0x903
24606
24607         cancel_lru_locks MGC
24608
24609         FAIL_ON_ERROR=true cleanup
24610         FAIL_ON_ERROR=true setup
24611 }
24612 run_test 900 "umount should not race with any mgc requeue thread"
24613
24614 # LUS-6253/LU-11185
24615 test_901() {
24616         local oldc
24617         local newc
24618         local olds
24619         local news
24620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24621
24622         # some get_param have a bug to handle dot in param name
24623         cancel_lru_locks MGC
24624         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24625         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24626         umount_client $MOUNT || error "umount failed"
24627         mount_client $MOUNT || error "mount failed"
24628         cancel_lru_locks MGC
24629         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24630         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24631
24632         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24633         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24634
24635         return 0
24636 }
24637 run_test 901 "don't leak a mgc lock on client umount"
24638
24639 # LU-13377
24640 test_902() {
24641         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24642                 skip "client does not have LU-13377 fix"
24643         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24644         $LCTL set_param fail_loc=0x1415
24645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24646         cancel_lru_locks osc
24647         rm -f $DIR/$tfile
24648 }
24649 run_test 902 "test short write doesn't hang lustre"
24650
24651 complete $SECONDS
24652 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24653 check_and_cleanup_lustre
24654 if [ "$I_MOUNTED" != "yes" ]; then
24655         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24656 fi
24657 exit_status