+test_90() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+ local pid1
+ local pid2
+ local duration=180
+
+ [ "$SLOW" = "yes" ] && duration=600
+ # Open/Create under striped directory
+ (
+ cd $DIR1
+ while true; do
+ $LFS mkdir -c$MDSCOUNT $tdir > /dev/null 2>&1
+ touch $tdir/f{0..3} > /dev/null 2>&1
+ done
+ ) &
+ pid1=$!
+ echo "start pid $pid1 to open/create under striped directory"
+
+ # unlink the striped directory at the same time
+ (
+ cd $DIR2
+ while true; do
+ rm -rf $tdir > /dev/null 2>&1
+ done
+ ) &
+ pid2=$!
+ echo "start pid $pid2 to unlink striped directory"
+
+ sleep $duration
+
+ kill $pid1 $pid2
+ wait $pid1 $pid2
+
+ return 0
+}
+run_test 90 "open/create and unlink striped directory"
+
+test_91() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+ local pid1
+ local pid2
+ local duration=180
+
+ [ "$SLOW" = "yes" ] && duration=600
+ # chmod striped directory
+ (
+ cd $DIR1
+ while true; do
+ $LFS mkdir -c$MDSCOUNT $tdir > /dev/null 2>&1
+ chmod go+w $tdir > /dev/null 2>&1
+ done
+ ) &
+ pid1=$!
+ echo "start pid $pid1 to chmod striped directory"
+
+ # unlink the striped directory at the same time
+ (
+ cd $DIR2
+ while true; do
+ rm -rf $tdir > /dev/null 2>&1
+ done
+ ) &
+ pid2=$!
+ echo "start pid $pid2 to unlink striped directory"
+
+ sleep $duration
+
+ kill $pid1 $pid2
+ wait $pid1 $pid2
+
+ return 0
+}
+run_test 91 "chmod and unlink striped directory"
+
+test_92() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+
+ local fd=$(free_fd)
+ local cmd="exec $fd<$DIR1/$tdir"
+ $LFS setdirstripe -c$MDSCOUNT $DIR1/$tdir || error "mkdir $tdir fails"
+ eval $cmd
+ cmd="exec $fd<&-"
+ trap "eval $cmd" EXIT
+ cd $DIR1/$tdir || error "cd $DIR1/$tdir fails"
+ rmdir ../$tdir || error "rmdir ../$tdir fails"
+
+ #define OBD_FAIL_LLITE_NO_CHECK_DEAD 0x1408
+ $LCTL set_param fail_loc=0x1408
+ mkdir $DIR2/$tdir/dir && error "create dir succeeds"
+ $LFS setdirstripe -i1 $DIR2/$tdir/remote_dir &&
+ error "create remote dir succeeds"
+ $LCTL set_param fail_loc=0
+ eval $cmd
+ return 0
+}
+run_test 92 "create remote directory under orphan directory"
+
+test_93() {
+ local rc1=0
+ local rc2=0
+ local old_rr
+
+ mkdir -p $DIR1/$tfile-1/
+ mkdir -p $DIR2/$tfile-2/
+ local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
+ 'lod.lustre-MDT*/qos_threshold_rr' | sed -e 's/%//')
+ do_facet $SINGLEMDS lctl set_param -n \
+ 'lod.lustre-MDT*/qos_threshold_rr' 100
+ #define OBD_FAIL_MDS_LOV_CREATE_RACE 0x163
+ do_facet $SINGLEMDS "lctl set_param fail_loc=0x00000163"
+
+ $LFS setstripe -c -1 $DIR1/$tfile-1/file1 &
+ local PID1=$!
+ sleep 1
+ $LFS setstripe -c -1 $DIR2/$tfile-2/file2 &
+ local PID2=$!
+ wait $PID2
+ wait $PID1
+ do_facet $SINGLEMDS "lctl set_param fail_loc=0x0"
+ do_facet $SINGLEMDS "lctl set_param -n \
+ 'lod.lustre-MDT*/qos_threshold_rr' $old_rr"
+
+ $LFS getstripe $DIR1/$tfile-1/file1
+ rc1=$($LFS getstripe -q $DIR1/$tfile-1/file1 |
+ awk '{if (/[0-9]/) print $1 }' | sort | uniq -d | wc -l)
+ $LFS getstripe $DIR2/$tfile-2/file2
+ rc2=$($LFS getstripe -q $DIR2/$tfile-2/file2 |
+ awk '{if (/[0-9]/) print $1 }' | sort | uniq -d | wc -l)
+ echo "rc1=$rc1 and rc2=$rc2 "
+ [ $rc1 -eq 0 ] && [ $rc2 -eq 0 ] ||
+ error "object allocate on same ost detected"
+}
+run_test 93 "alloc_rr should not allocate on same ost"
+
+# Data-on-MDT tests
+test_100a() {
+ skip "Reserved for glimpse-ahead" && return
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
+ skip "Need MDS version at least 2.10.55"
+
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
+
+ lctl set_param -n mdc.*.stats=clear
+ dd if=/dev/zero of=$DIR2/$tdir/dom bs=4096 count=1 || return 1
+
+ $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #1"
+ # first stat from server should return size data and save glimpse
+ local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
+ [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
+ # second stat to check size is NOT cached on client without IO lock
+ $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #2"
+
+ local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
+ [ $gls -ge 1 ] || error "Expect glimpse RPCs but none"
+ rm -f $dom
+}
+run_test 100a "DoM: glimpse RPCs for stat without IO lock (DoM only file)"
+
+test_100b() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
+ skip "Need MDS version at least 2.10.55"
+
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
+
+ lctl set_param -n mdc.*.stats=clear
+ dd if=/dev/zero of=$DIR2/$tdir/dom bs=4096 count=1 || return 1
+ cancel_lru_locks mdc
+ # first stat data from server should have size
+ $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #1"
+ # second stat to check size is cached on client
+ $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #2"
+
+ local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
+ # both stats should cause no glimpse requests
+ [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
+ rm -f $dom
+}
+run_test 100b "DoM: no glimpse RPC for stat with IO lock (DoM only file)"
+
+test_100c() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
+ skip "Need MDS version at least 2.10.55"
+
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
+
+ lctl set_param -n mdc.*.stats=clear
+ lctl set_param -n osc.*.stats=clear
+ dd if=/dev/zero of=$DIR2/$tdir/dom bs=2048K count=1 || return 1
+
+ # check that size is merged from MDT and OST correctly
+ $CHECKSTAT -t file -s 2097152 $DIR/$tdir/dom ||
+ error "Wrong size from stat #1"
+
+ local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
+ [ $gls -eq 0 ] && error "Expect OST glimpse RPCs but got none"
+
+ rm -f $dom
+}
+run_test 100c "DoM: write vs stat without IO lock (combined file)"
+
+test_100d() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
+ skip "Need MDS version at least 2.10.55"
+
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
+
+
+ dd if=/dev/zero of=$DIR2/$tdir/dom bs=2048K count=1 || return 1
+ lctl set_param -n mdc.*.stats=clear
+ $TRUNCATE $DIR2/$tdir/dom 4096
+
+ # check that reported size is valid after file grows to OST and
+ # is truncated back to MDT stripe size
+ $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom ||
+ error "Wrong size from stat #1"
+
+ local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
+ [ $gls -eq 0 ] && error "Expect OST glimpse but got none"
+
+ rm -f $dom
+}
+run_test 100d "DoM: write+truncate vs stat without IO lock (combined file)"
+
+test_100e() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.50) ] &&
+ skip "Need MDS version at least 2.11.50"
+
+ local dom=$DIR/$tdir/dom
+ local dom2=$DIR2/$tdir/dom
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt $DIR/$tdir
+
+ cancel_lru_locks mdc
+ dd if=/dev/urandom of=$dom bs=12000 count=1
+ $TRUNCATE $dom2 6000
+ cancel_lru_locks mdc
+ lctl set_param -n mdc.*.stats=clear
+ # expect read-on-open to return all data before write
+ cat /etc/hosts >> $dom
+ local read=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
+ [[ $read -eq 0 ]] || error "Unexpected $read READ RPCs"
+}
+run_test 100e "DoM: read on open and file size"
+
+test_101a() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
+ skip "Need MDS version at least 2.10.55" && return
+
+ $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
+ # to get layout
+ $CHECKSTAT -t file $DIR1/$tfile
+
+ local old_wb=$(sysctl -n vm.dirty_writeback_centisecs)
+ sysctl -wq vm.dirty_writeback_centisecs=0
+
+ trap "sysctl -wq vm.dirty_writeback_centisecs=$old_wb" EXIT
+
+ # open + IO lock
+ dd if=/dev/zero of=$DIR1/$tfile bs=4096 count=1 ||
+ error_noexit "Write fails"
+ # must discard pages
+ lctl set_param -n mdc.*.stats=clear
+ rm $DIR2/$tfile || error "Unlink fails"
+
+ local writes=$(lctl get_param -n mdc.*.stats | grep -c ost_write)
+ [ $writes -eq 0 ] || error "Found WRITE RPC but expect none"
+}
+run_test 101a "Discard DoM data on unlink"
+
+test_101b() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
+ skip "Need MDS version at least 2.10.55" && return
+
+ $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
+ touch $DIR1/${tfile}_2
+ # to get layout
+ $CHECKSTAT -t file $DIR1/$tfile
+
+ local old_wb=$(sysctl -n vm.dirty_writeback_centisecs)
+ sysctl -wq vm.dirty_writeback_centisecs=0
+
+ trap "sysctl -wq vm.dirty_writeback_centisecs=$old_wb" EXIT
+
+ # open + IO lock
+ dd if=/dev/zero of=$DIR1/$tfile bs=4096 count=1 || error "Write fails"
+ # must discard pages
+ lctl set_param -n mdc.*.stats=clear
+ mv $DIR2/${tfile}_2 $DIR2/$tfile || error "Rename fails"
+
+ local writes=$(lctl get_param -n mdc.*.stats | grep -c ost_write)
+ [ $writes -eq 0 ] || error "Found WRITE RPC but expect none"
+}
+run_test 101b "Discard DoM data on rename"
+
+test_101c() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
+ skip "Need MDS version at least 2.10.55" && return
+
+ $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
+ # to get layout
+ $CHECKSTAT -t file $DIR1/$tfile
+
+ local old_wb=$(sysctl -n vm.dirty_writeback_centisecs)
+ sysctl -wq vm.dirty_writeback_centisecs=0
+
+ trap "sysctl -wq vm.dirty_writeback_centisecs=$old_wb" EXIT
+
+ # open + IO lock
+ dd if=/dev/zero of=$DIR1/$tfile bs=4096 count=1 || error "Write fails"
+ $MULTIOP $DIR1/$tfile O_c &
+ MULTIOP_PID=$!
+ sleep 1
+ lctl set_param -n mdc.*.stats=clear
+ rm $DIR2/$tfile > /dev/null || error "Unlink fails for opened file"
+ kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
+
+ local writes=$(lctl get_param -n mdc.*.stats | grep -c ost_write)
+ [ $writes -eq 0 ] || error "Found WRITE RPC but expect none"
+}
+run_test 101c "Discard DoM data on close-unlink"
+
+# test to verify file handle related system calls
+# (name_to_handle_at/open_by_handle_at)
+# The new system calls are supported in glibc >= 2.14.
+
+# test to verify we can open by handle an unlinked file from > 1 client
+# This test opens the file normally on $DIR1, which is on one mount, and then
+# opens it by handle on $DIR2, which is on a different mount.
+test_102() {
+ [ $MDS1_VERSION -lt $(version_code 2.11.57) ] &&
+ skip "Needs MDS version 2.11.57 or later"
+
+ echo "Test file_handle syscalls" > $DIR/$tfile ||
+ error "write failed"
+ check_fhandle_syscalls $DIR/$tfile $DIR2 ||
+ error "check_fhandle_syscalls failed"
+ rm -f $DIR2/$tfile
+}
+run_test 102 "Test open by handle of unlinked file"
+