summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Farnum <greg@inktank.com>2013-04-08 09:10:35 -0700
committerGreg Farnum <greg@inktank.com>2013-04-08 09:10:35 -0700
commitedc9ddfde956a4f737d63df98777b0ee2c2f6bcc (patch)
tree3ddf5df0bb09906eb37719c40102c1e430de6eed
parent5b4cb53781cc6d3b0fcba939255e4aef8f19f83d (diff)
downloadceph-edc9ddfde956a4f737d63df98777b0ee2c2f6bcc.tar.gz
mds: fix journaler to set temp_fetch_len appropriately and read the requested amount
The _prefetch() function which intereprets temp_fetch_len interprets it as the amount of data we need from read_pos, which is the beginning of read_buf. So by setting it to the amount *more* we needed, we were getting stuck forever if we actually hit this condition. Fix it by setting temp_fetch_len based on the amount of data we need in aggregate. Furthermore, we were previously rounding *down* the requested amount in order to read only full log segments. Round up instead! Fixes #4618 Signed-off-by: Greg Farnum <greg@inktank.com>
-rw-r--r--src/osdc/Journaler.cc17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/osdc/Journaler.cc b/src/osdc/Journaler.cc
index 544ac8c49c4..0bda7ce9058 100644
--- a/src/osdc/Journaler.cc
+++ b/src/osdc/Journaler.cc
@@ -835,6 +835,7 @@ void Journaler::_issue_read(uint64_t len)
void Journaler::_prefetch()
{
+ ldout(cct, 10) << "_prefetch" << dendl;
// prefetch
uint64_t pf;
if (temp_fetch_len) {
@@ -847,9 +848,11 @@ void Journaler::_prefetch()
uint64_t raw_target = read_pos + pf;
- // only read full log segments
+ // read full log segments, so increase if necessary
uint64_t period = get_layout_period();
- uint64_t target = raw_target - (raw_target % period);
+ uint64_t remainder = raw_target % period;
+ uint64_t adjustment = remainder ? period - remainder : 0;
+ uint64_t target = raw_target + adjustment;
// don't read past the log tail
if (target > write_pos)
@@ -883,7 +886,9 @@ bool Journaler::_is_readable()
read_buf.length() >= sizeof(s) + s)
return true; // yep, next entry is ready.
- // darn it!
+ ldout (cct, 10) << "_is_readable read_buf.length() == " << read_buf.length()
+ << ", but need " << s + sizeof(s)
+ << " for next entry; fetch_len is " << fetch_len << dendl;
// partial fragment at the end?
if (received_pos == write_pos) {
@@ -902,12 +907,14 @@ bool Journaler::_is_readable()
return false;
}
- uint64_t need = (sizeof(s)+s-read_buf.length());
+ uint64_t need = sizeof(s) + s;
if (need > fetch_len) {
+ temp_fetch_len = sizeof(s) + s;
ldout(cct, 10) << "_is_readable noting temp_fetch_len " << temp_fetch_len
<< " for len " << s << " entry" << dendl;
- temp_fetch_len = need;
}
+
+ ldout(cct, 10) << "_is_readable: not readable, returning false" << dendl;
return false;
}