]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: allocate new journal tag when acquiring exclusive lock
authorJason Dillaman <dillaman@redhat.com>
Fri, 26 Feb 2016 16:25:15 +0000 (11:25 -0500)
committerJason Dillaman <dillaman@redhat.com>
Tue, 8 Mar 2016 14:03:43 +0000 (09:03 -0500)
The journal tag tracks a write epoch within the image, so before
allowing writes to proceed, ensure the journal entries will be
stored under a new epoch.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/exclusive_lock/AcquireRequest.cc
src/librbd/exclusive_lock/AcquireRequest.h

index e46714778a368a8e5a252c90c0790c6fe60d0202..d973bf21fc624011a198cdefc4bb7efed1e37b2a 100644 (file)
@@ -166,12 +166,64 @@ Context *AcquireRequest<I>::handle_open_journal(int *ret_val) {
   if (*ret_val < 0) {
     lderr(cct) << "failed to open journal: " << cpp_strerror(*ret_val) << dendl;
     m_error_result = *ret_val;
-    return send_close_object_map();
+    send_close_journal();
+    return nullptr;
+  }
+
+  send_allocate_journal_tag();
+  return nullptr;
+}
+
+template <typename I>
+void AcquireRequest<I>::send_allocate_journal_tag() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  if (!m_journal->is_tag_owner()) {
+    lderr(cct) << "local image not promoted" << dendl;
+    m_error_result = -EPERM;
+    send_close_journal();
+    return;
   }
 
+  using klass = AcquireRequest<I>;
+  Context *ctx = create_context_callback<
+    klass, &klass::handle_allocate_journal_tag>(this);
+  m_journal->allocate_tag(Journal<I>::LOCAL_MIRROR_UUID, ctx);
+}
+
+template <typename I>
+Context *AcquireRequest<I>::handle_allocate_journal_tag(int *ret_val) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << ": r=" << *ret_val << dendl;
+
+  if (*ret_val < 0) {
+    m_error_result = *ret_val;
+    send_close_journal();
+    return nullptr;
+  }
   return m_on_finish;
 }
 
+template <typename I>
+void AcquireRequest<I>::send_close_journal() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  using klass = AcquireRequest<I>;
+  Context *ctx = create_context_callback<klass, &klass::handle_close_journal>(
+    this);
+  m_journal->close(ctx);
+}
+
+template <typename I>
+Context *AcquireRequest<I>::handle_close_journal(int *ret_val) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << ": r=" << *ret_val << dendl;
+
+  return send_close_object_map(ret_val);
+}
+
 template <typename I>
 Context *AcquireRequest<I>::send_open_object_map() {
   if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP)) {
@@ -201,9 +253,9 @@ Context *AcquireRequest<I>::handle_open_object_map(int *ret_val) {
 }
 
 template <typename I>
-Context *AcquireRequest<I>::send_close_object_map() {
+Context *AcquireRequest<I>::send_close_object_map(int *ret_val) {
   if (m_object_map == nullptr) {
-    revert();
+    revert(ret_val);
     return m_on_finish;
   }
 
@@ -224,11 +276,7 @@ Context *AcquireRequest<I>::handle_close_object_map(int *ret_val) {
 
   // object map should never result in an error
   assert(*ret_val == 0);
-
-  assert(m_error_result < 0);
-  *ret_val = m_error_result;
-
-  revert();
+  revert(ret_val);
   return m_on_finish;
 }
 
@@ -439,13 +487,16 @@ void AcquireRequest<I>::apply() {
 }
 
 template <typename I>
-void AcquireRequest<I>::revert() {
+void AcquireRequest<I>::revert(int *ret_val) {
   RWLock::WLocker snap_locker(m_image_ctx.snap_lock);
   m_image_ctx.object_map = nullptr;
   m_image_ctx.journal = nullptr;
 
   delete m_object_map;
   delete m_journal;
+
+  assert(m_error_result < 0);
+  *ret_val = m_error_result;
 }
 
 } // namespace exclusive_lock
index dc03829af4feb513d8d99953fe1dfbd55be1a724..2c4e05b86ceef569f086796fe755cb60302bfa06 100644 (file)
@@ -39,25 +39,33 @@ private:
    *    v
    * FLUSH_NOTIFIES
    *    |
-   *    |     /---------------------------------------------------------\
-   *    |     |                                                         |
-   *    |     |             (no lockers)                                |
-   *    |     |   . . . . . . . . . . . . . . . . . . . . .             |
-   *    |     |   .                                       .             |
-   *    |     v   v      (EBUSY)                          .             |
-   *    \--> LOCK_IMAGE * * * * * * * > GET_LOCKERS . . . .             |
-   *          .   |                       |                             |
-   *    . . . .   |                       |                             |
-   *    .         v                       v                             |
-   *    .     OPEN_OBJECT_MAP           GET_WATCHERS . . .              |
-   *    .         |                       |              .              |
-   *    .         v                       v              .              |
-   *    . . > OPEN_JOURNAL * *          BLACKLIST        . (blacklist   |
-   *    .         |          *            |              .  disabled)   |
-   *    .         |          v            v              .              |
-   *    .         | CLOSE_OBJECT_MAP    BREAK_LOCK < . . .              |
-   *    .         v          |            |                             |
-   *    . . > <finish> <-----/            \-----------------------------/
+   *    |     /-----------------------------------------------------------\
+   *    |     |                                                           |
+   *    |     |             (no lockers)                                  |
+   *    |     |   . . . . . . . . . . . . . . . . . . . . . .             |
+   *    |     |   .                                         .             |
+   *    |     v   v      (EBUSY)                            .             |
+   *    \--> LOCK_IMAGE * * * * * * * >   GET_LOCKERS . . . .             |
+   *          .   |                         |                             |
+   *    . . . .   |                         |                             |
+   *    .         v                         v                             |
+   *    .     OPEN_OBJECT_MAP             GET_WATCHERS . . .              |
+   *    .         |                         |              .              |
+   *    .         v                         v              .              |
+   *    . . > OPEN_JOURNAL * * * * * *    BLACKLIST        . (blacklist   |
+   *    .         |                  *      |              .  disabled)   |
+   *    .         v                  *      v              .              |
+   *    .     ALLOCATE_JOURNAL_TAG   *    BREAK_LOCK < . . .              |
+   *    .         |            *     *      |                             |
+   *    .         |            *     *      \-----------------------------/
+   *    .         |            v     v
+   *    .         |         CLOSE_JOURNAL
+   *    .         |               |
+   *    .         |               v
+   *    .         |         CLOSE_OBJECT_MAP
+   *    .         |               |
+   *    .         v               |
+   *    . . > <finish> <----------/
    *
    * @endverbatim
    */
@@ -94,10 +102,16 @@ private:
   Context *send_open_journal();
   Context *handle_open_journal(int *ret_val);
 
+  void send_allocate_journal_tag();
+  Context *handle_allocate_journal_tag(int *ret_val);
+
+  void send_close_journal();
+  Context *handle_close_journal(int *ret_val);
+
   Context *send_open_object_map();
   Context *handle_open_object_map(int *ret_val);
 
-  Context *send_close_object_map();
+  Context *send_close_object_map(int *ret_val);
   Context *handle_close_object_map(int *ret_val);
 
   void send_get_lockers();
@@ -113,7 +127,7 @@ private:
   Context *handle_break_lock(int *ret_val);
 
   void apply();
-  void revert();
+  void revert(int *ret_val);
 };
 
 } // namespace exclusive_lock