journal::TagData tag_data;
if (!client.commit_position.object_positions.empty()) {
auto position = client.commit_position.object_positions.front();
- tag_data.predecessor_commit_valid = true;
- tag_data.predecessor_tag_tid = position.tag_tid;
- tag_data.predecessor_entry_tid = position.entry_tid;
+ tag_data.predecessor.commit_valid = true;
+ tag_data.predecessor.tag_tid = position.tag_tid;
+ tag_data.predecessor.entry_tid = position.entry_tid;
}
- tag_data.predecessor_mirror_uuid = prev_tag_data.mirror_uuid;
+ tag_data.predecessor.mirror_uuid = prev_tag_data.mirror_uuid;
tag_data.mirror_uuid = mirror_uuid;
bufferlist tag_bl;
CephContext *cct = m_image_ctx.cct;
ldout(cct, 20) << this << " " << __func__ << dendl;
- bool predecessor_commit_valid = false;
- uint64_t predecessor_tag_tid = 0;
- uint64_t predecessor_entry_tid = 0;
+ journal::TagPredecessor predecessor;
+ predecessor.mirror_uuid = LOCAL_MIRROR_UUID;
{
Mutex::Locker locker(m_lock);
assert(m_journaler != nullptr && is_tag_owner());
assert(m_tag_data.mirror_uuid == LOCAL_MIRROR_UUID);
if (!client.commit_position.object_positions.empty()) {
auto position = client.commit_position.object_positions.front();
- predecessor_commit_valid = true;
- predecessor_tag_tid = position.tag_tid;
- predecessor_entry_tid = position.entry_tid;
+ predecessor.commit_valid = true;
+ predecessor.tag_tid = position.tag_tid;
+ predecessor.entry_tid = position.entry_tid;
}
}
- allocate_tag(LOCAL_MIRROR_UUID, LOCAL_MIRROR_UUID, predecessor_commit_valid,
- predecessor_tag_tid, predecessor_entry_tid, on_finish);
+ allocate_tag(LOCAL_MIRROR_UUID, predecessor, on_finish);
}
template <typename I>
void Journal<I>::allocate_tag(const std::string &mirror_uuid,
- const std::string &predecessor_mirror_uuid,
- bool predecessor_commit_valid,
- uint64_t predecessor_tag_tid,
- uint64_t predecessor_entry_tid,
+ const journal::TagPredecessor &predecessor,
Context *on_finish) {
CephContext *cct = m_image_ctx.cct;
ldout(cct, 20) << this << " " << __func__ << ": mirror_uuid=" << mirror_uuid
journal::TagData tag_data;
tag_data.mirror_uuid = mirror_uuid;
- tag_data.predecessor_mirror_uuid = predecessor_mirror_uuid;
- tag_data.predecessor_commit_valid = predecessor_commit_valid;
- tag_data.predecessor_tag_tid = predecessor_tag_tid;
- tag_data.predecessor_entry_tid = predecessor_entry_tid;
+ tag_data.predecessor = predecessor;
bufferlist tag_bl;
::encode(tag_data, tag_bl);
void allocate_local_tag(Context *on_finish);
void allocate_tag(const std::string &mirror_uuid,
- const std::string &predecessor_mirror_uuid,
- bool predecessor_commit_valid, uint64_t predecessor_tag_tid,
- uint64_t predecessor_entry_tid, Context *on_finish);
+ const journal::TagPredecessor &predecessor,
+ Context *on_finish);
void flush_commit_position(Context *on_finish);
// Journal Tag
+void TagPredecessor::encode(bufferlist& bl) const {
+ ::encode(mirror_uuid, bl);
+ ::encode(commit_valid, bl);
+ ::encode(tag_tid, bl);
+ ::encode(entry_tid, bl);
+}
+
+void TagPredecessor::decode(bufferlist::iterator& it) {
+ ::decode(mirror_uuid, it);
+ ::decode(commit_valid, it);
+ ::decode(tag_tid, it);
+ ::decode(entry_tid, it);
+}
+
+void TagPredecessor::dump(Formatter *f) const {
+ f->dump_string("mirror_uuid", mirror_uuid);
+ f->dump_string("commit_valid", commit_valid ? "true" : "false");
+ f->dump_unsigned("tag_tid", tag_tid);
+ f->dump_unsigned("entry_tid", entry_tid);
+}
+
void TagData::encode(bufferlist& bl) const {
::encode(mirror_uuid, bl);
- ::encode(predecessor_mirror_uuid, bl);
- ::encode(predecessor_commit_valid, bl);
- ::encode(predecessor_tag_tid, bl);
- ::encode(predecessor_entry_tid, bl);
+ predecessor.encode(bl);
}
void TagData::decode(bufferlist::iterator& it) {
::decode(mirror_uuid, it);
- ::decode(predecessor_mirror_uuid, it);
- ::decode(predecessor_commit_valid, it);
- ::decode(predecessor_tag_tid, it);
- ::decode(predecessor_entry_tid, it);
+ predecessor.decode(it);
}
void TagData::dump(Formatter *f) const {
f->dump_string("mirror_uuid", mirror_uuid);
- f->dump_string("predecessor_mirror_uuid", predecessor_mirror_uuid);
- f->dump_string("predecessor_commit_valid",
- predecessor_commit_valid ? "true" : "false");
- f->dump_unsigned("predecessor_tag_tid", predecessor_tag_tid);
- f->dump_unsigned("predecessor_entry_tid", predecessor_entry_tid);
+ f->open_object_section("predecessor");
+ predecessor.dump(f);
+ f->close_section();
}
void TagData::generate_test_instances(std::list<TagData *> &o) {
return out;
}
-std::ostream &operator<<(std::ostream &out, const TagData &tag_data) {
+std::ostream &operator<<(std::ostream &out, const TagPredecessor &predecessor) {
out << "["
- << "mirror_uuid=" << tag_data.mirror_uuid << ", "
- << "predecessor_mirror_uuid=" << tag_data.predecessor_mirror_uuid;
- if (tag_data.predecessor_commit_valid) {
+ << "mirror_uuid=" << predecessor.mirror_uuid;
+ if (predecessor.commit_valid) {
out << ", "
- << "predecessor_tag_tid=" << tag_data.predecessor_tag_tid << ", "
- << "predecessor_entry_tid=" << tag_data.predecessor_entry_tid;
+ << "tag_tid=" << predecessor.tag_tid << ", "
+ << "entry_tid=" << predecessor.entry_tid;
}
out << "]";
return out;
}
+std::ostream &operator<<(std::ostream &out, const TagData &tag_data) {
+ out << "["
+ << "mirror_uuid=" << tag_data.mirror_uuid << ", "
+ << "predecessor=" << tag_data.predecessor
+ << "]";
+ return out;
+}
+
} // namespace journal
} // namespace librbd
// Journal Tag data structures
+struct TagPredecessor {
+ std::string mirror_uuid; // empty if local
+ bool commit_valid = false;
+ uint64_t tag_tid = 0;
+ uint64_t entry_tid = 0;
+
+ TagPredecessor() {
+ }
+ TagPredecessor(const std::string &mirror_uuid, bool commit_valid,
+ uint64_t tag_tid, uint64_t entry_tid)
+ : mirror_uuid(mirror_uuid), commit_valid(commit_valid), tag_tid(tag_tid),
+ entry_tid(entry_tid) {
+ }
+
+ inline bool operator==(const TagPredecessor &rhs) const {
+ return (mirror_uuid == rhs.mirror_uuid &&
+ commit_valid == rhs.commit_valid &&
+ tag_tid == rhs.tag_tid &&
+ entry_tid == rhs.entry_tid);
+ }
+
+ void encode(bufferlist& bl) const;
+ void decode(bufferlist::iterator& it);
+ void dump(Formatter *f) const;
+};
+
struct TagData {
// owner of the tag (exclusive lock epoch)
std::string mirror_uuid; // empty if local
// mapping to last committed record of previous tag
- std::string predecessor_mirror_uuid; // empty if local
- bool predecessor_commit_valid = false;
- uint64_t predecessor_tag_tid = 0;
- uint64_t predecessor_entry_tid = 0;
+ TagPredecessor predecessor;
TagData() {
}
bool predecessor_commit_valid,
uint64_t predecessor_tag_tid, uint64_t predecessor_entry_tid)
: mirror_uuid(mirror_uuid),
- predecessor_mirror_uuid(predecessor_mirror_uuid),
- predecessor_commit_valid(predecessor_commit_valid),
- predecessor_tag_tid(predecessor_tag_tid),
- predecessor_entry_tid(predecessor_entry_tid) {
+ predecessor(predecessor_mirror_uuid, predecessor_commit_valid,
+ predecessor_tag_tid, predecessor_entry_tid) {
}
void encode(bufferlist& bl) const;
std::ostream &operator<<(std::ostream &out, const MirrorPeerSyncPoint &sync);
std::ostream &operator<<(std::ostream &out, const MirrorPeerState &meta);
std::ostream &operator<<(std::ostream &out, const MirrorPeerClientMeta &meta);
+std::ostream &operator<<(std::ostream &out, const TagPredecessor &predecessor);
std::ostream &operator<<(std::ostream &out, const TagData &tag_data);
enum class ListenerType : int8_t {
MOCK_CONST_METHOD0(is_tag_owner, bool());
MOCK_CONST_METHOD1(is_tag_owner, int(bool *));
- MOCK_METHOD6(allocate_tag, void(const std::string &mirror_uuid,
- const std::string &predecessor_mirror_uuid,
- bool predecessor_commit_valid,
- uint64_t predecessor_tag_tid,
- uint64_t predecessor_entry_tid,
+ MOCK_METHOD3(allocate_tag, void(const std::string &mirror_uuid,
+ const journal::TagPredecessor &predecessor,
Context *on_finish));
MOCK_METHOD1(open, void(Context *));
m_stop_requested = true;
}
- std::string predecessor_mirror_uuid =
- m_replay_tag_data.predecessor_mirror_uuid;
- if (predecessor_mirror_uuid == librbd::Journal<>::LOCAL_MIRROR_UUID) {
- predecessor_mirror_uuid = m_remote_mirror_uuid;
- } else if (predecessor_mirror_uuid == m_local_mirror_uuid) {
- predecessor_mirror_uuid = librbd::Journal<>::LOCAL_MIRROR_UUID;
+ librbd::journal::TagPredecessor predecessor(m_replay_tag_data.predecessor);
+ if (predecessor.mirror_uuid == librbd::Journal<>::LOCAL_MIRROR_UUID) {
+ predecessor.mirror_uuid = m_remote_mirror_uuid;
+ } else if (predecessor.mirror_uuid == m_local_mirror_uuid) {
+ predecessor.mirror_uuid = librbd::Journal<>::LOCAL_MIRROR_UUID;
}
dout(20) << "mirror_uuid=" << mirror_uuid << ", "
- << "predecessor_mirror_uuid=" << predecessor_mirror_uuid << ", "
+ << "predecessor_mirror_uuid=" << predecessor.mirror_uuid << ", "
<< "replay_tag_tid=" << m_replay_tag_tid << ", "
<< "replay_tag_data=" << m_replay_tag_data << dendl;
Context *ctx = create_context_callback<
ImageReplayer, &ImageReplayer<I>::handle_allocate_local_tag>(this);
- m_local_journal->allocate_tag(
- mirror_uuid, predecessor_mirror_uuid,
- m_replay_tag_data.predecessor_commit_valid,
- m_replay_tag_data.predecessor_tag_tid,
- m_replay_tag_data.predecessor_entry_tid,
- ctx);
+ m_local_journal->allocate_tag(mirror_uuid, predecessor, ctx);
}
template <typename I>
dout(10) << ": decoded remote tag " << tag.tid << ": "
<< remote_tag_data << dendl;
if (remote_tag_data.mirror_uuid == librbd::Journal<>::ORPHAN_MIRROR_UUID &&
- remote_tag_data.predecessor_mirror_uuid == m_local_mirror_uuid) {
+ remote_tag_data.predecessor.mirror_uuid == m_local_mirror_uuid) {
// remote tag is chained off a local tag demotion
break;
}
if (local_tag_data.mirror_uuid == librbd::Journal<>::ORPHAN_MIRROR_UUID &&
remote_tag_data.mirror_uuid == librbd::Journal<>::ORPHAN_MIRROR_UUID &&
- remote_tag_data.predecessor_mirror_uuid == m_local_mirror_uuid) {
+ remote_tag_data.predecessor.mirror_uuid == m_local_mirror_uuid) {
dout(20) << ": local image was demoted" << dendl;
} else if (local_tag_data.mirror_uuid == m_remote_mirror_uuid &&
m_client_meta->state == librbd::journal::MIRROR_PEER_STATE_REPLAYING) {
}
librbd::journal::TagData &tag_data = tag_it->second;
m_entries_behind_master += master.entry_tid;
- master = cls::journal::ObjectPosition(0, tag_data.predecessor_tag_tid,
- tag_data.predecessor_entry_tid);
+ master = cls::journal::ObjectPosition(0, tag_data.predecessor.tag_tid,
+ tag_data.predecessor.entry_tid);
}
m_entries_behind_master += master.entry_tid - m_mirror_position.entry_tid;
dout(20) << "erasing tag " << tag_data << "for tag_tid " << tag_tid
<< dendl;
- tag_tid = tag_data.predecessor_tag_tid;
+ tag_tid = tag_data.predecessor.tag_tid;
m_tag_cache.erase(tag_it);
}
}
}
- if (tag_data.predecessor_tag_tid == 0) {
+ if (tag_data.predecessor.tag_tid == 0) {
// We failed. Don't consider this fatal, just terminate retrieving.
dout(20) << "making fake tag" << dendl;
- tag_data.predecessor_tag_tid = mirror_tag_tid;
+ tag_data.predecessor.tag_tid = mirror_tag_tid;
}
dout(20) << "decoded tag " << master_tag_tid << ": " << tag_data << dendl;
m_tag_cache.insert(std::make_pair(master_tag_tid, tag_data));
- send_update_tag_cache(tag_data.predecessor_tag_tid, mirror_tag_tid);
+ send_update_tag_cache(tag_data.predecessor.tag_tid, mirror_tag_tid);
}
template <typename I>