diff options
Diffstat (limited to 'src/journal/ObjectPlayer.cc')
-rw-r--r-- | src/journal/ObjectPlayer.cc | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/journal/ObjectPlayer.cc b/src/journal/ObjectPlayer.cc index cc55674a884..0a85b8853f2 100644 --- a/src/journal/ObjectPlayer.cc +++ b/src/journal/ObjectPlayer.cc @@ -12,6 +12,36 @@ namespace journal { +namespace { + +bool advance_to_last_pad_byte(uint32_t off, bufferlist::const_iterator *iter, + uint32_t *pad_len, bool *partial_entry) { + const uint32_t MAX_PAD = 8; + auto pad_bytes = MAX_PAD - off % MAX_PAD; + auto next = *iter; + + ceph_assert(!next.end()); + if (*next != '\0') { + return false; + } + + for (auto i = pad_bytes - 1; i > 0; i--) { + if ((++next).end()) { + *partial_entry = true; + return false; + } + if (*next != '\0') { + return false; + } + } + + *iter = next; + *pad_len += pad_bytes; + return true; +} + +} // anonymous namespace + ObjectPlayer::ObjectPlayer(librados::IoCtx &ioctx, const std::string &object_oid_prefix, uint64_t object_num, SafeTimer &timer, @@ -131,6 +161,7 @@ int ObjectPlayer::handle_fetch_complete(int r, const bufferlist &bl, clear_invalid_range(m_read_bl_off, m_read_bl.length()); bufferlist::const_iterator iter{&m_read_bl, 0}; + uint32_t pad_len = 0; while (!iter.end()) { uint32_t bytes_needed; uint32_t bl_off = iter.get_off(); @@ -149,9 +180,21 @@ int ObjectPlayer::handle_fetch_complete(int r, const bufferlist &bl, break; } - if (!invalid) { + if (!invalid && + !advance_to_last_pad_byte(m_read_bl_off + iter.get_off(), &iter, + &pad_len, &partial_entry)) { invalid_start_off = m_read_bl_off + bl_off; invalid = true; + if (partial_entry) { + if (full_fetch) { + lderr(m_cct) << ": partial pad at offset " << invalid_start_off + << dendl; + } else { + ldout(m_cct, 20) << ": partial pad detected, will re-fetch" + << dendl; + } + break; + } lderr(m_cct) << ": detected corrupt journal entry at offset " << invalid_start_off << dendl; } @@ -172,6 +215,8 @@ int ObjectPlayer::handle_fetch_complete(int r, const bufferlist &bl, m_invalid_ranges.insert(invalid_start_off, invalid_end_off - invalid_start_off); invalid = false; + + m_read_bl_off = invalid_end_off; } EntryKey entry_key(std::make_pair(entry.get_tag_tid(), @@ -191,7 +236,8 @@ int ObjectPlayer::handle_fetch_complete(int r, const bufferlist &bl, iter = bufferlist::iterator(&m_read_bl, 0); // advance the decoded entry offset - m_read_bl_off += entry_len; + m_read_bl_off += entry_len + pad_len; + pad_len = 0; } if (invalid) { |