#include "journal/Journaler.h"
#include "journal/ReplayEntry.h"
#include "common/errno.h"
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_base_of.hpp>
#define dout_subsys ceph_subsys_rbd
#undef dout_prefix
const std::string CLIENT_DESCRIPTION = "master image";
-struct SetOpRequestTid : public boost::static_visitor<void> {
- uint64_t tid;
-
- SetOpRequestTid(uint64_t _tid) : tid(_tid) {
- }
-
- template <typename Event>
- typename boost::enable_if<boost::is_base_of<journal::OpEventBase, Event>,
- void>::type
- operator()(Event &event) const {
- event.tid = tid;
- }
-
- template <typename Event>
- typename boost::disable_if<boost::is_base_of<journal::OpEventBase, Event>,
- void>::type
- operator()(Event &event) const {
- assert(false);
- }
-};
-
template <typename ImageCtxT>
struct C_ReplayCommitted : public Context {
typedef journal::TypeTraits<ImageCtxT> TypeTraits;
}
template <typename I>
-uint64_t Journal<I>::append_op_event(journal::EventEntry &event_entry) {
+void Journal<I>::append_op_event(uint64_t op_tid,
+ journal::EventEntry &event_entry) {
assert(m_image_ctx.owner_lock.is_locked());
- uint64_t tid;
+ bufferlist bl;
+ ::encode(event_entry, bl);
{
Mutex::Locker locker(m_lock);
assert(m_state == STATE_READY);
-
- Mutex::Locker event_locker(m_event_lock);
- tid = ++m_event_tid;
- assert(tid != 0);
-
- // inject the generated tid into the provided event entry
- boost::apply_visitor(SetOpRequestTid(tid), event_entry.event);
-
- bufferlist bl;
- ::encode(event_entry, bl);
m_journaler->committed(m_journaler->append("", bl));
}
CephContext *cct = m_image_ctx.cct;
ldout(cct, 10) << this << " " << __func__ << ": "
- << "event=" << event_entry.get_event_type() << ", "
- << "tid=" << tid << dendl;
- return tid;
+ << "op_tid=" << op_tid << ", "
+ << "event=" << event_entry.get_event_type() << dendl;
}
template <typename I>
void Journal<I>::commit_op_event(uint64_t tid, int r) {
CephContext *cct = m_image_ctx.cct;
- ldout(cct, 10) << this << " " << __func__ << ": tid=" << tid << dendl;
+ ldout(cct, 10) << this << " " << __func__ << ": tid=" << tid << ", "
+ << "r=" << r << dendl;
journal::EventEntry event_entry((journal::OpFinishEvent(tid, r)));
{
Mutex::Locker locker(m_lock);
assert(m_state == STATE_READY);
-
m_journaler->committed(m_journaler->append("", bl));
}
}
#define CEPH_LIBRBD_JOURNAL_H
#include "include/int_types.h"
+#include "include/atomic.h"
#include "include/Context.h"
#include "include/interval_set.h"
#include "include/unordered_map.h"
void commit_io_event_extent(uint64_t tid, uint64_t offset, uint64_t length,
int r);
- uint64_t append_op_event(journal::EventEntry &event_entry);
- void commit_op_event(uint64_t tid, int r);
+ void append_op_event(uint64_t op_tid, journal::EventEntry &event_entry);
+ void commit_op_event(uint64_t op_tid, int r);
void flush_event(uint64_t tid, Context *on_safe);
void wait_event(uint64_t tid, Context *on_safe);
+ uint64_t allocate_op_tid() {
+ uint64_t op_tid = m_op_tid.inc();
+ assert(op_tid != 0);
+ return op_tid;
+ }
+
private:
ImageCtxT &m_image_ctx;
uint64_t m_event_tid;
Events m_events;
+ atomic_t m_op_tid;
+
bool m_blocking_writes;
journal::Replay<ImageCtxT> *m_journal_replay;
}
void OpEventBase::encode(bufferlist& bl) const {
- ::encode(tid, bl);
+ ::encode(op_tid, bl);
}
void OpEventBase::decode(__u8 version, bufferlist::iterator& it) {
- ::decode(tid, it);
+ ::decode(op_tid, it);
}
void OpEventBase::dump(Formatter *f) const {
- f->dump_unsigned("tid", tid);
+ f->dump_unsigned("op_tid", op_tid);
+}
+
+void OpFinishEvent::encode(bufferlist& bl) const {
+ OpEventBase::encode(bl);
+ ::encode(op_tid, bl);
+ ::encode(r, bl);
+}
+
+void OpFinishEvent::decode(__u8 version, bufferlist::iterator& it) {
+ OpEventBase::decode(version, it);
+ ::decode(op_tid, it);
+ ::decode(r, it);
+}
+
+void OpFinishEvent::dump(Formatter *f) const {
+ OpEventBase::dump(f);
+ f->dump_unsigned("op_tid", op_tid);
+ f->dump_int("result", r);
}
void SnapEventBase::encode(bufferlist& bl) const {
- OpStartEventBase::encode(bl);
+ OpEventBase::encode(bl);
::encode(snap_name, bl);
}
void SnapEventBase::decode(__u8 version, bufferlist::iterator& it) {
- OpStartEventBase::decode(version, it);
+ OpEventBase::decode(version, it);
::decode(snap_name, it);
}
void SnapEventBase::dump(Formatter *f) const {
- OpStartEventBase::dump(f);
+ OpEventBase::dump(f);
f->dump_string("snap_name", snap_name);
}
}
void SnapRenameEvent::dump(Formatter *f) const {
- OpStartEventBase::dump(f);
+ SnapEventBase::dump(f);
f->dump_unsigned("src_snap_id", snap_id);
f->dump_string("dest_snap_name", snap_name);
}
void RenameEvent::encode(bufferlist& bl) const {
- OpStartEventBase::encode(bl);
+ OpEventBase::encode(bl);
::encode(image_name, bl);
}
void RenameEvent::decode(__u8 version, bufferlist::iterator& it) {
- OpStartEventBase::decode(version, it);
+ OpEventBase::decode(version, it);
::decode(image_name, it);
}
void RenameEvent::dump(Formatter *f) const {
- OpStartEventBase::dump(f);
+ OpEventBase::dump(f);
f->dump_string("image_name", image_name);
}
void ResizeEvent::encode(bufferlist& bl) const {
- OpStartEventBase::encode(bl);
+ OpEventBase::encode(bl);
::encode(size, bl);
}
void ResizeEvent::decode(__u8 version, bufferlist::iterator& it) {
- OpStartEventBase::decode(version, it);
+ OpEventBase::decode(version, it);
::decode(size, it);
}
void ResizeEvent::dump(Formatter *f) const {
- OpStartEventBase::dump(f);
+ OpEventBase::dump(f);
f->dump_unsigned("size", size);
}
o.push_back(new EventEntry(SnapRemoveEvent(345, "snap")));
o.push_back(new EventEntry(SnapRenameEvent()));
- o.push_back(new EventEntry(SnapRenameEvent(345, 1, "snap")));
+ o.push_back(new EventEntry(SnapRenameEvent(456, 1, "snap")));
o.push_back(new EventEntry(SnapProtectEvent()));
- o.push_back(new EventEntry(SnapProtectEvent(456, "snap")));
+ o.push_back(new EventEntry(SnapProtectEvent(567, "snap")));
o.push_back(new EventEntry(SnapUnprotectEvent()));
- o.push_back(new EventEntry(SnapUnprotectEvent(567, "snap")));
+ o.push_back(new EventEntry(SnapUnprotectEvent(678, "snap")));
o.push_back(new EventEntry(SnapRollbackEvent()));
- o.push_back(new EventEntry(SnapRollbackEvent(678, "snap")));
+ o.push_back(new EventEntry(SnapRollbackEvent(789, "snap")));
o.push_back(new EventEntry(RenameEvent()));
- o.push_back(new EventEntry(RenameEvent(789, "image name")));
+ o.push_back(new EventEntry(RenameEvent(890, "image name")));
o.push_back(new EventEntry(ResizeEvent()));
- o.push_back(new EventEntry(ResizeEvent(890, 1234)));
+ o.push_back(new EventEntry(ResizeEvent(901, 1234)));
- o.push_back(new EventEntry(FlattenEvent(901)));
+ o.push_back(new EventEntry(FlattenEvent(123)));
}
} // namespace journal
};
struct OpEventBase {
- uint64_t tid;
-
- virtual void encode(bufferlist& bl) const;
- virtual void decode(__u8 version, bufferlist::iterator& it);
- virtual void dump(Formatter *f) const;
+ uint64_t op_tid;
protected:
- OpEventBase() : tid(0) {
+ OpEventBase() : op_tid(0) {
}
- OpEventBase(uint64_t _tid) : tid(_tid) {
+ OpEventBase(uint64_t op_tid) : op_tid(op_tid) {
}
- virtual ~OpEventBase() {}
-};
-struct OpStartEventBase : public OpEventBase {
-protected:
- OpStartEventBase() {
- }
- OpStartEventBase(uint64_t tid) : OpEventBase(tid) {
- }
+ void encode(bufferlist& bl) const;
+ void decode(__u8 version, bufferlist::iterator& it);
+ void dump(Formatter *f) const;
};
struct OpFinishEvent : public OpEventBase {
OpFinishEvent() : r(0) {
}
- OpFinishEvent(uint64_t tid, int _r) : OpEventBase(tid), r(_r) {
+ OpFinishEvent(uint64_t op_tid, int r) : OpEventBase(op_tid), r(r) {
}
+
+ void encode(bufferlist& bl) const;
+ void decode(__u8 version, bufferlist::iterator& it);
+ void dump(Formatter *f) const;
};
-struct SnapEventBase : public OpStartEventBase {
+struct SnapEventBase : public OpEventBase {
std::string snap_name;
+protected:
SnapEventBase() {
}
- SnapEventBase(uint64_t tid, const std::string &_snap_name)
- : OpStartEventBase(tid), snap_name(_snap_name) {
+ SnapEventBase(uint64_t op_tid, const std::string &_snap_name)
+ : OpEventBase(op_tid), snap_name(_snap_name) {
}
- virtual void encode(bufferlist& bl) const;
- virtual void decode(__u8 version, bufferlist::iterator& it);
- virtual void dump(Formatter *f) const;
+ void encode(bufferlist& bl) const;
+ void decode(__u8 version, bufferlist::iterator& it);
+ void dump(Formatter *f) const;
};
struct SnapCreateEvent : public SnapEventBase {
SnapCreateEvent() {
}
- SnapCreateEvent(uint64_t tid, const std::string &snap_name)
- : SnapEventBase(tid, snap_name) {
+ SnapCreateEvent(uint64_t op_tid, const std::string &snap_name)
+ : SnapEventBase(op_tid, snap_name) {
}
+
+ using SnapEventBase::encode;
+ using SnapEventBase::decode;
+ using SnapEventBase::dump;
};
struct SnapRemoveEvent : public SnapEventBase {
SnapRemoveEvent() {
}
- SnapRemoveEvent(uint64_t tid, const std::string &snap_name)
- : SnapEventBase(tid, snap_name) {
+ SnapRemoveEvent(uint64_t op_tid, const std::string &snap_name)
+ : SnapEventBase(op_tid, snap_name) {
}
+
+ using SnapEventBase::encode;
+ using SnapEventBase::decode;
+ using SnapEventBase::dump;
};
struct SnapRenameEvent : public SnapEventBase {
SnapRenameEvent() : snap_id(CEPH_NOSNAP) {
}
- SnapRenameEvent(uint64_t tid, uint64_t src_snap_id,
+ SnapRenameEvent(uint64_t op_tid, uint64_t src_snap_id,
const std::string &dest_snap_name)
- : SnapEventBase(tid, dest_snap_name), snap_id(src_snap_id) {
+ : SnapEventBase(op_tid, dest_snap_name), snap_id(src_snap_id) {
}
- virtual void encode(bufferlist& bl) const;
- virtual void decode(__u8 version, bufferlist::iterator& it);
- virtual void dump(Formatter *f) const;
+ void encode(bufferlist& bl) const;
+ void decode(__u8 version, bufferlist::iterator& it);
+ void dump(Formatter *f) const;
};
struct SnapProtectEvent : public SnapEventBase {
SnapProtectEvent() {
}
- SnapProtectEvent(uint64_t tid, const std::string &snap_name)
- : SnapEventBase(tid, snap_name) {
+ SnapProtectEvent(uint64_t op_tid, const std::string &snap_name)
+ : SnapEventBase(op_tid, snap_name) {
}
+
+ using SnapEventBase::encode;
+ using SnapEventBase::decode;
+ using SnapEventBase::dump;
};
struct SnapUnprotectEvent : public SnapEventBase {
SnapUnprotectEvent() {
}
- SnapUnprotectEvent(uint64_t tid, const std::string &snap_name)
- : SnapEventBase(tid, snap_name) {
+ SnapUnprotectEvent(uint64_t op_tid, const std::string &snap_name)
+ : SnapEventBase(op_tid, snap_name) {
}
+
+ using SnapEventBase::encode;
+ using SnapEventBase::decode;
+ using SnapEventBase::dump;
};
struct SnapRollbackEvent : public SnapEventBase {
SnapRollbackEvent() {
}
- SnapRollbackEvent(uint64_t tid, const std::string &snap_name)
- : SnapEventBase(tid, snap_name) {
+ SnapRollbackEvent(uint64_t op_tid, const std::string &snap_name)
+ : SnapEventBase(op_tid, snap_name) {
}
+
+ using SnapEventBase::encode;
+ using SnapEventBase::decode;
+ using SnapEventBase::dump;
};
-struct RenameEvent : public OpStartEventBase {
+struct RenameEvent : public OpEventBase {
static const EventType EVENT_TYPE = EVENT_TYPE_RENAME;
std::string image_name;
RenameEvent() {
}
- RenameEvent(uint64_t tid, const std::string &_image_name)
- : OpStartEventBase(tid), image_name(_image_name) {
+ RenameEvent(uint64_t op_tid, const std::string &_image_name)
+ : OpEventBase(op_tid), image_name(_image_name) {
}
- virtual void encode(bufferlist& bl) const;
- virtual void decode(__u8 version, bufferlist::iterator& it);
- virtual void dump(Formatter *f) const;
+ void encode(bufferlist& bl) const;
+ void decode(__u8 version, bufferlist::iterator& it);
+ void dump(Formatter *f) const;
};
-struct ResizeEvent : public OpStartEventBase {
+struct ResizeEvent : public OpEventBase {
static const EventType EVENT_TYPE = EVENT_TYPE_RESIZE;
uint64_t size;
ResizeEvent() : size(0) {
}
- ResizeEvent(uint64_t tid, uint64_t _size)
- : OpStartEventBase(tid), size(_size) {
+ ResizeEvent(uint64_t op_tid, uint64_t _size)
+ : OpEventBase(op_tid), size(_size) {
}
- virtual void encode(bufferlist& bl) const;
- virtual void decode(__u8 version, bufferlist::iterator& it);
- virtual void dump(Formatter *f) const;
+ void encode(bufferlist& bl) const;
+ void decode(__u8 version, bufferlist::iterator& it);
+ void dump(Formatter *f) const;
};
-struct FlattenEvent : public OpStartEventBase {
+struct FlattenEvent : public OpEventBase {
static const EventType EVENT_TYPE = EVENT_TYPE_FLATTEN;
FlattenEvent() {
}
- FlattenEvent(uint64_t tid) : OpStartEventBase(tid) {
+ FlattenEvent(uint64_t op_tid) : OpEventBase(op_tid) {
}
+
+ using OpEventBase::encode;
+ using OpEventBase::decode;
+ using OpEventBase::dump;
};
struct UnknownEvent {
virtual void send_op();
virtual bool should_complete(int r);
- virtual journal::Event create_event() const {
- return journal::FlattenEvent(0);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::FlattenEvent(op_tid);
}
private:
virtual void send_op();
virtual bool should_complete(int r);
- virtual journal::Event create_event() const {
- return journal::RenameEvent(0, m_dest_name);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::RenameEvent(op_tid, m_dest_name);
}
private:
template <typename I>
Request<I>::Request(I &image_ctx, Context *on_finish)
- : AsyncRequest<I>(image_ctx, on_finish), m_tid(0) {
+ : AsyncRequest<I>(image_ctx, on_finish) {
}
template <typename I>
return;
}
- journal::EventEntry event_entry(create_event());
- m_tid = image_ctx.journal->append_op_event(event_entry);
+ m_op_tid = image_ctx.journal->allocate_op_tid();
+ journal::EventEntry event_entry(create_event(m_op_tid));
+ image_ctx.journal->append_op_event(m_op_tid, event_entry);
}
}
{
I &image_ctx = this->m_image_ctx;
RWLock::RLocker snap_locker(image_ctx.snap_lock);
- if (m_tid != 0 && image_ctx.journal != NULL &&
+ if (m_op_tid != 0 && image_ctx.journal != NULL &&
!image_ctx.journal->is_journal_replaying()) {
// ops will be canceled / completed before closing journal
assert(image_ctx.journal->is_journal_ready());
- image_ctx.journal->commit_op_event(m_tid, r);
+ image_ctx.journal->commit_op_event(m_op_tid, r);
}
}
virtual void finish(int r);
virtual void send_op() = 0;
- virtual journal::Event create_event() const = 0;
+ virtual journal::Event create_event(uint64_t op_tid) const = 0;
private:
struct C_WaitForJournalReady : public Context {
}
};
- uint64_t m_tid;
+ uint64_t m_op_tid = 0;
void handle_journal_ready();
};
virtual void send_op();
virtual bool should_complete(int r);
- virtual journal::Event create_event() const {
- return journal::ResizeEvent(0, m_new_size);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::ResizeEvent(op_tid, m_new_size);
}
private:
return r;
}
- virtual journal::Event create_event() const {
- return journal::SnapCreateEvent(0, m_snap_name);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::SnapCreateEvent(op_tid, m_snap_name);
}
private:
virtual void send_op();
virtual bool should_complete(int r);
- virtual journal::Event create_event() const {
- return journal::SnapProtectEvent(0, m_snap_name);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::SnapProtectEvent(op_tid, m_snap_name);
}
private:
virtual void send_op();
virtual bool should_complete(int r);
- virtual journal::Event create_event() const {
- return journal::SnapRemoveEvent(0, m_snap_name);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::SnapRemoveEvent(op_tid, m_snap_name);
}
private:
SnapshotRenameRequest(ImageCtxT &image_ctx, Context *on_finish,
uint64_t snap_id, const std::string &snap_name);
- virtual journal::Event create_event() const {
- return journal::SnapRenameEvent(0, m_snap_id, m_snap_name);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::SnapRenameEvent(op_tid, m_snap_id, m_snap_name);
}
protected:
virtual void send_op();
virtual bool should_complete(int r);
- virtual journal::Event create_event() const {
- return journal::SnapRollbackEvent(0, m_snap_name);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::SnapRollbackEvent(op_tid, m_snap_name);
}
private:
return 0;
}
- virtual journal::Event create_event() const {
- return journal::SnapUnprotectEvent(0, m_snap_name);
+ virtual journal::Event create_event(uint64_t op_tid) const {
+ return journal::SnapUnprotectEvent(op_tid, m_snap_name);
}
private:
MOCK_METHOD1(open, void(Context *));
MOCK_METHOD1(close, void(Context *));
- MOCK_METHOD1(append_op_event, uint64_t(journal::EventEntry&));
+ MOCK_METHOD0(allocate_op_tid, uint64_t());
+ MOCK_METHOD2(append_op_event, void(uint64_t, journal::EventEntry&));
MOCK_METHOD2(commit_op_event, void(uint64_t, int));
};