]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: inform the journal when pending IO safely commits
authorJason Dillaman <dillaman@redhat.com>
Wed, 15 Jul 2015 21:32:28 +0000 (17:32 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 13 Nov 2015 04:27:06 +0000 (23:27 -0500)
When caching is disabled, the AioCompletion notifies the journal that
the update is safe.  When caching is enabled, writeback can result
in partial write extents being overwritten (and no longer associated
to the original journal event).  In this case, the writeback handler
is responsible for informing the journal when writes are safe.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/AioCompletion.cc
src/librbd/AioCompletion.h
src/librbd/AioImageRequest.cc
src/librbd/Journal.cc

index 982a03fc7f7982940d705e681dc1154ea7882a59..ac6754d19a097e69443171c6545ea1548f2ce6c5 100644 (file)
@@ -14,6 +14,7 @@
 #include "librbd/internal.h"
 
 #include "librbd/AioCompletion.h"
+#include "librbd/Journal.h"
 
 #ifdef WITH_LTTNG
 #include "tracing/librbd.h"
@@ -86,6 +87,12 @@ namespace librbd {
       break;
     }
 
+    // inform the journal that the op has successfully committed
+    if (journal_tid != 0) {
+      assert(ictx->journal != NULL);
+      ictx->journal->commit_event(journal_tid, rval);
+    }
+
     // note: possible for image to be closed after op marked finished
     if (async_op.started()) {
       async_op.finish_op();
@@ -148,6 +155,12 @@ namespace librbd {
     put_unlock();
   }
 
+  void AioCompletion::associate_journal_event(uint64_t tid) {
+    Mutex::Locker l(lock);
+    assert(!done);
+    journal_tid = tid;
+  }
+
   bool AioCompletion::is_complete() {
     tracepoint(librbd, aio_is_complete_enter, this);
     bool done;
index 94ed682dd2e8bbea17e27c83cd2171ad2d18baab..532f7e261536c1821ad7fc11ecc43b049ce5e6b5 100644 (file)
@@ -62,13 +62,16 @@ namespace librbd {
 
     AsyncOperation async_op;
 
+    uint64_t journal_tid;
+
     AioCompletion() : lock("AioCompletion::lock", true, false),
                      done(false), rval(0), complete_cb(NULL),
                      complete_arg(NULL), rbd_comp(NULL),
                      pending_count(0), blockers(1),
                      ref(1), released(false), ictx(NULL),
                      aio_type(AIO_TYPE_NONE),
-                     read_bl(NULL), read_buf(NULL), read_buf_len(0) {
+                     read_bl(NULL), read_buf(NULL), read_buf_len(0),
+                      journal_tid(0) {
     }
     ~AioCompletion() {
     }
@@ -99,6 +102,8 @@ namespace librbd {
 
     void complete_request(CephContext *cct, ssize_t r);
 
+    void associate_journal_event(uint64_t tid);
+
     bool is_complete();
 
     ssize_t get_return_value();
index a902adcaf4f4bf329591e006c79238127573df2e..daa99ecad9b301f51299bc079021d9565821163d 100644 (file)
@@ -50,6 +50,29 @@ struct C_DiscardJournalCommit : public Context {
   }
 };
 
+struct C_FlushJournalCommit : public Context {
+  ImageCtx &image_ctx;
+  AioCompletion *aio_comp;
+
+  C_FlushJournalCommit(ImageCtx &_image_ctx, AioCompletion *_aio_comp,
+                       uint64_t tid)
+    : image_ctx(_image_ctx), aio_comp(_aio_comp) {
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << this << " C_FlushJournalCommit: "
+                   << "delaying flush until journal tid " << tid << " "
+                   << "safe" << dendl;
+
+    aio_comp->add_request();
+  }
+
+  virtual void finish(int r) {
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << this << " C_FlushJournalCommit: journal committed"
+                   << dendl;
+    aio_comp->complete_request(cct, r);
+  }
+};
+
 } // anonymous namespace
 
 void AioImageRequest::aio_read(
@@ -275,8 +298,13 @@ uint64_t AioImageWrite::append_journal_event(
   bl.append(m_buf, m_len);
 
   journal::EventEntry event_entry(journal::AioWriteEvent(m_off, m_len, bl));
-  return m_image_ctx.journal->append_event(m_aio_comp, event_entry, requests,
-                                           m_off, m_len, synchronous);
+  uint64_t tid = m_image_ctx.journal->append_event(m_aio_comp, event_entry,
+                                                   requests, m_off, m_len,
+                                                   synchronous);
+  if (m_image_ctx.object_cacher == NULL) {
+    m_aio_comp->associate_journal_event(tid);
+  }
+  return tid;
 }
 
 void AioImageWrite::send_cache_requests(const ObjectExtents &object_extents,
@@ -330,8 +358,11 @@ void AioImageWrite::update_stats(size_t length) {
 uint64_t AioImageDiscard::append_journal_event(
     const AioObjectRequests &requests, bool synchronous) {
   journal::EventEntry event_entry(journal::AioDiscardEvent(m_off, m_len));
-  return m_image_ctx.journal->append_event(m_aio_comp, event_entry, requests,
-                                           m_off, m_len, synchronous);
+  uint64_t tid = m_image_ctx.journal->append_event(m_aio_comp, event_entry,
+                                                   requests, m_off, m_len,
+                                                   synchronous);
+  m_aio_comp->associate_journal_event(tid);
+  return tid;
 }
 
 void AioImageDiscard::send_cache_requests(const ObjectExtents &object_extents,
@@ -387,9 +418,15 @@ void AioImageFlush::send_request() {
     // journal the flush event
     RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
     if (m_image_ctx.journal != NULL) {
-      m_image_ctx.journal->append_event(
+      uint64_t journal_tid = m_image_ctx.journal->append_event(
         m_aio_comp, journal::EventEntry(journal::AioFlushEvent()),
-        AioObjectRequests(), 0, 0, true);
+        AioObjectRequests(), 0, 0, false);
+
+      C_FlushJournalCommit *ctx = new C_FlushJournalCommit(m_image_ctx,
+                                                           m_aio_comp,
+                                                           journal_tid);
+      m_image_ctx.journal->flush_event(journal_tid, ctx);
+      m_aio_comp->associate_journal_event(journal_tid);
     }
   }
 
index 1278ef36cf75465278539dbf053e5e42cfc42b7d..ab848160101d45d5ab31e593816a172f72b8fba5 100644 (file)
@@ -312,13 +312,13 @@ void Journal::destroy_journaler() {
 
 void Journal::complete_event(Events::iterator it, int r) {
   assert(m_lock.is_locked());
+  assert(m_state == STATE_RECORDING);
 
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << ": tid=" << it->first << " "
                  << "r=" << r << dendl;
 
-  // TODO
-
+  m_journaler->committed(it->second.future);
   m_events.erase(it);
 }