]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
journal: update commit entry object number upon overflow
authorJason Dillaman <dillaman@redhat.com>
Mon, 23 May 2016 16:15:49 +0000 (12:15 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 24 May 2016 16:58:55 +0000 (12:58 -0400)
Otherwise the recorded object positions might point to an older
object that doesn't contain the actual entry.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/journal/JournalMetadata.cc
src/journal/JournalMetadata.h
src/journal/JournalRecorder.cc
src/test/journal/test_JournalRecorder.cc

index c24a96aa0ef2bb586aac3b809a289b8f5301f9a9..6c9ffd61cb45ee60757ad4d27549eb203b519401 100644 (file)
@@ -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;
index db30cf15951a3b75f7b0597c99cd599bb9166204..3ded24bb565dd90ffeacc73f39f74a16ceb17db2 100644 (file)
@@ -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();
index ce66a1314437322078528161548e9bfcc567bfb6..b4da4ff006737a963c900a35c1b992a5edd6f15e 100644 (file)
@@ -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;
index 149e63b11d41ffc1c6cc8a101f695f7288c7d2c8..c06ea6df5b5a46fb7b6d327fc6705496374156ed 100644 (file)
@@ -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);
+}
+