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)) {
}
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;
}
// 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;
}
}
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
* 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
*/
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();
Context *handle_break_lock(int *ret_val);
void apply();
- void revert();
+ void revert(int *ret_val);
};
} // namespace exclusive_lock