From: Jason Dillaman Date: Fri, 26 Feb 2016 16:25:15 +0000 (-0500) Subject: librbd: allocate new journal tag when acquiring exclusive lock X-Git-Tag: v10.1.0~187^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=16d5e695c3780ef2de7dd6cc31369c329bf05a36;p=ceph.git librbd: allocate new journal tag when acquiring exclusive lock 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 --- diff --git a/src/librbd/exclusive_lock/AcquireRequest.cc b/src/librbd/exclusive_lock/AcquireRequest.cc index e46714778a36..d973bf21fc62 100644 --- a/src/librbd/exclusive_lock/AcquireRequest.cc +++ b/src/librbd/exclusive_lock/AcquireRequest.cc @@ -166,12 +166,64 @@ Context *AcquireRequest::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 +void AcquireRequest::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; + Context *ctx = create_context_callback< + klass, &klass::handle_allocate_journal_tag>(this); + m_journal->allocate_tag(Journal::LOCAL_MIRROR_UUID, ctx); +} + +template +Context *AcquireRequest::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 +void AcquireRequest::send_close_journal() { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 10) << __func__ << dendl; + + using klass = AcquireRequest; + Context *ctx = create_context_callback( + this); + m_journal->close(ctx); +} + +template +Context *AcquireRequest::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 Context *AcquireRequest::send_open_object_map() { if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP)) { @@ -201,9 +253,9 @@ Context *AcquireRequest::handle_open_object_map(int *ret_val) { } template -Context *AcquireRequest::send_close_object_map() { +Context *AcquireRequest::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::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::apply() { } template -void AcquireRequest::revert() { +void AcquireRequest::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 diff --git a/src/librbd/exclusive_lock/AcquireRequest.h b/src/librbd/exclusive_lock/AcquireRequest.h index dc03829af4fe..2c4e05b86cee 100644 --- a/src/librbd/exclusive_lock/AcquireRequest.h +++ b/src/librbd/exclusive_lock/AcquireRequest.h @@ -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 | | | - * . . > <-----/ \-----------------------------/ + * | /-----------------------------------------------------------\ + * | | | + * | | (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 | + * . . > <----------/ * * @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