From: Jason Dillaman Date: Mon, 23 May 2016 16:15:49 +0000 (-0400) Subject: journal: update commit entry object number upon overflow X-Git-Tag: v11.0.0~428^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5fbf5f82de8214c5c676d38feae7682a006fcab1;p=ceph.git journal: update commit entry object number upon overflow Otherwise the recorded object positions might point to an older object that doesn't contain the actual entry. Signed-off-by: Jason Dillaman --- diff --git a/src/journal/JournalMetadata.cc b/src/journal/JournalMetadata.cc index c24a96aa0ef2..6c9ffd61cb45 100644 --- a/src/journal/JournalMetadata.cc +++ b/src/journal/JournalMetadata.cc @@ -853,6 +853,34 @@ uint64_t JournalMetadata::allocate_commit_tid(uint64_t object_num, return commit_tid; } +void JournalMetadata::overflow_commit_tid(uint64_t commit_tid, + uint64_t object_num) { + Mutex::Locker locker(m_lock); + + auto it = m_pending_commit_tids.find(commit_tid); + assert(it != m_pending_commit_tids.end()); + assert(it->second.object_num < object_num); + + ldout(m_cct, 20) << __func__ << ": " + << "commit_tid=" << commit_tid << ", " + << "old_object_num=" << it->second.object_num << ", " + << "new_object_num=" << object_num << dendl; + it->second.object_num = object_num; +} + +void JournalMetadata::get_commit_entry(uint64_t commit_tid, + uint64_t *object_num, + uint64_t *tag_tid, uint64_t *entry_tid) { + Mutex::Locker locker(m_lock); + + auto it = m_pending_commit_tids.find(commit_tid); + assert(it != m_pending_commit_tids.end()); + + *object_num = it->second.object_num; + *tag_tid = it->second.tag_tid; + *entry_tid = it->second.entry_tid; +} + void JournalMetadata::committed(uint64_t commit_tid, const CreateContext &create_context) { ldout(m_cct, 20) << "committed tid=" << commit_tid << dendl; diff --git a/src/journal/JournalMetadata.h b/src/journal/JournalMetadata.h index db30cf15951a..3ded24bb565d 100644 --- a/src/journal/JournalMetadata.h +++ b/src/journal/JournalMetadata.h @@ -140,6 +140,9 @@ public: uint64_t allocate_commit_tid(uint64_t object_num, uint64_t tag_tid, uint64_t entry_tid); + void overflow_commit_tid(uint64_t commit_tid, uint64_t object_num); + void get_commit_entry(uint64_t commit_tid, uint64_t *object_num, + uint64_t *tag_tid, uint64_t *entry_tid); void committed(uint64_t commit_tid, const CreateContext &create_context); void notify_update(); diff --git a/src/journal/JournalRecorder.cc b/src/journal/JournalRecorder.cc index ce66a1314437..b4da4ff00673 100644 --- a/src/journal/JournalRecorder.cc +++ b/src/journal/JournalRecorder.cc @@ -254,6 +254,14 @@ void JournalRecorder::create_next_object_recorder( << "new oid=" << new_object_recorder->get_oid() << dendl; AppendBuffers append_buffers; object_recorder->claim_append_buffers(&append_buffers); + + // update the commit record to point to the correct object number + for (auto &append_buffer : append_buffers) { + m_journal_metadata->overflow_commit_tid( + append_buffer.first->get_commit_tid(), + new_object_recorder->get_object_number()); + } + new_object_recorder->append(append_buffers); m_object_ptrs[splay_offset] = new_object_recorder; diff --git a/src/test/journal/test_JournalRecorder.cc b/src/test/journal/test_JournalRecorder.cc index 149e63b11d41..c06ea6df5b5a 100644 --- a/src/test/journal/test_JournalRecorder.cc +++ b/src/test/journal/test_JournalRecorder.cc @@ -139,3 +139,38 @@ TEST_F(TestJournalRecorder, Flush) { ASSERT_TRUE(future2.is_complete()); } +TEST_F(TestJournalRecorder, OverflowCommitObjectNumber) { + std::string oid = get_temp_oid(); + ASSERT_EQ(0, create(oid, 12, 2)); + ASSERT_EQ(0, client_register(oid)); + + journal::JournalMetadataPtr metadata = create_metadata(oid); + ASSERT_EQ(0, init_metadata(metadata)); + ASSERT_EQ(0U, metadata->get_active_set()); + + journal::JournalRecorder *recorder = create_recorder(oid, metadata); + + recorder->append(123, create_payload(std::string(metadata->get_object_size() - + journal::Entry::get_fixed_size(), '1'))); + journal::Future future2 = recorder->append(124, create_payload(std::string(1, '2'))); + + C_SaferCond cond; + future2.flush(&cond); + ASSERT_EQ(0, cond.wait()); + + ASSERT_EQ(1U, metadata->get_active_set()); + + uint64_t object_num; + uint64_t tag_tid; + uint64_t entry_tid; + metadata->get_commit_entry(1, &object_num, &tag_tid, &entry_tid); + ASSERT_EQ(0U, object_num); + ASSERT_EQ(123U, tag_tid); + ASSERT_EQ(0U, entry_tid); + + metadata->get_commit_entry(2, &object_num, &tag_tid, &entry_tid); + ASSERT_EQ(2U, object_num); + ASSERT_EQ(124U, tag_tid); + ASSERT_EQ(0U, entry_tid); +} +