#include "librbd/internal.h"
#include "librbd/AioCompletion.h"
+#include "librbd/Journal.h"
#ifdef WITH_LTTNG
#include "tracing/librbd.h"
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();
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;
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() {
}
void complete_request(CephContext *cct, ssize_t r);
+ void associate_journal_event(uint64_t tid);
+
bool is_complete();
ssize_t get_return_value();
}
};
+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(
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,
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,
// 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);
}
}