public:
pg_info_t info;
- PG::Log log;
+ pg_log_t log;
PG::Missing missing;
epoch_t get_epoch() { return epoch; }
}
-/******* PG::Log ********/
-
-void PG::Log::copy_after(const Log &other, eversion_t v)
-{
- head = other.head;
- tail = other.tail;
- for (list<pg_log_entry_t>::const_reverse_iterator i = other.log.rbegin();
- i != other.log.rend();
- i++) {
- assert(i->version > other.tail);
- if (i->version <= v) {
- // make tail accurate.
- tail = i->version;
- break;
- }
- log.push_front(*i);
- }
-}
-
-void PG::Log::copy_range(const Log &other, eversion_t from, eversion_t to)
-{
- list<pg_log_entry_t>::const_reverse_iterator i = other.log.rbegin();
- assert(i != other.log.rend());
- while (i->version > to) {
- ++i;
- assert(i != other.log.rend());
- }
- assert(i->version == to);
- head = to;
- for ( ; i != other.log.rend(); ++i) {
- if (i->version <= from) {
- tail = i->version;
- break;
- }
- log.push_front(*i);
- }
-}
-
-void PG::Log::copy_up_to(const Log &other, int max)
-{
- int n = 0;
- head = other.head;
- tail = other.tail;
- for (list<pg_log_entry_t>::const_reverse_iterator i = other.log.rbegin();
- i != other.log.rend();
- ++i) {
- if (n++ >= max) {
- tail = i->version;
- break;
- }
- log.push_front(*i);
- }
-}
void PG::IndexedLog::trim(ObjectStore::Transaction& t, eversion_t s)
{
/********* PG **********/
-void PG::proc_master_log(ObjectStore::Transaction& t, pg_info_t &oinfo, Log &olog, Missing& omissing, int from)
+void PG::proc_master_log(ObjectStore::Transaction& t, pg_info_t &oinfo, pg_log_t &olog, Missing& omissing, int from)
{
dout(10) << "proc_master_log for osd." << from << ": " << olog << " " << omissing << dendl;
assert(!is_active() && is_primary());
}
void PG::proc_replica_log(ObjectStore::Transaction& t,
- pg_info_t &oinfo, Log &olog, Missing& omissing, int from)
+ pg_info_t &oinfo, pg_log_t &olog, Missing& omissing, int from)
{
dout(10) << "proc_replica_log for osd." << from << ": "
<< oinfo << " " << olog << " " << omissing << dendl;
}
void PG::merge_log(ObjectStore::Transaction& t,
- pg_info_t &oinfo, Log &olog, int fromosd)
+ pg_info_t &oinfo, pg_log_t &olog, int fromosd)
{
dout(10) << "merge_log " << olog << " from osd." << fromosd
<< " into " << log << dendl;
}
-ostream& PG::Log::print(ostream& out) const
-{
- out << *this << std::endl;
- for (list<pg_log_entry_t>::const_iterator p = log.begin();
- p != log.end();
- p++)
- out << *p << std::endl;
- return out;
-}
-
ostream& PG::IndexedLog::print(ostream& out) const
{
out << *this << std::endl;
std::string gen_prefix() const;
- /*
- * Log - incremental log of recent pg changes.
- * serves as a recovery queue for recent changes.
- */
- struct Log {
- /*
- * head - newest entry (update|delete)
- * tail - entry previous to oldest (update|delete) for which we have
- * complete negative information.
- * i.e. we can infer pg contents for any store whose last_update >= tail.
- */
- eversion_t head; // newest entry
- eversion_t tail; // version prior to oldest
-
- list<pg_log_entry_t> log; // the actual log.
-
- Log() {}
-
- void clear() {
- eversion_t z;
- head = tail = z;
- log.clear();
- }
-
- bool empty() const {
- return log.empty();
- }
-
- bool null() const {
- return head.version == 0 && head.epoch == 0;
- }
-
- size_t approx_size() const {
- return head.version - tail.version;
- }
-
- list<pg_log_entry_t>::iterator find_entry(eversion_t v) {
- int fromhead = head.version - v.version;
- int fromtail = v.version - tail.version;
- list<pg_log_entry_t>::iterator p;
- if (fromhead < fromtail) {
- p = log.end();
- p--;
- while (p->version > v)
- p--;
- return p;
- } else {
- p = log.begin();
- while (p->version < v)
- p++;
- return p;
- }
- }
-
- void encode(bufferlist& bl) const {
- __u8 struct_v = 2;
- ::encode(struct_v, bl);
- ::encode(head, bl);
- ::encode(tail, bl);
- ::encode(log, bl);
- }
- void decode(bufferlist::iterator &bl) {
- __u8 struct_v = 1;
- ::decode(struct_v, bl);
- ::decode(head, bl);
- ::decode(tail, bl);
- if (struct_v < 2) {
- bool backlog;
- ::decode(backlog, bl);
- }
- ::decode(log, bl);
- }
-
- /**
- * copy entries from the tail of another Log
- *
- * @param other Log to copy from
- * @param from copy entries after this version
- */
- void copy_after(const Log &other, eversion_t from);
-
- /**
- * copy a range of entries from another Log
- *
- * @param other Log to copy from
- * @param from copy entries after this version
- * @parem to up to and including this version
- */
- void copy_range(const Log &other, eversion_t from, eversion_t to);
-
- /**
- * copy up to N entries
- *
- * @param o source log
- * @param max max number of entreis to copy
- */
- void copy_up_to(const Log &other, int max);
-
- ostream& print(ostream& out) const;
- };
- WRITE_CLASS_ENCODER(Log)
-
/**
* IndexLog - adds in-memory index of the log, by oid.
* plus some methods to manipulate it all.
*/
- struct IndexedLog : public Log {
+ struct IndexedLog : public pg_log_t {
hash_map<hobject_t,pg_log_entry_t*> objects; // ptrs into log. be careful!
hash_map<osd_reqid_t,pg_log_entry_t*> caller_ops;
/****/
IndexedLog() {}
- void claim_log(const Log& o) {
+ void claim_log(const pg_log_t& o) {
log = o.log;
head = o.head;
tail = o.tail;
void zero() {
unindex();
- Log::clear();
+ pg_log_t::clear();
reset_recovery_pointers();
}
void reset_recovery_pointers() {
virtual void calc_trim_to() = 0;
- void proc_replica_log(ObjectStore::Transaction& t, pg_info_t &oinfo, Log &olog,
+ void proc_replica_log(ObjectStore::Transaction& t, pg_info_t &oinfo, pg_log_t &olog,
Missing& omissing, int from);
- void proc_master_log(ObjectStore::Transaction& t, pg_info_t &oinfo, Log &olog,
+ void proc_master_log(ObjectStore::Transaction& t, pg_info_t &oinfo, pg_log_t &olog,
Missing& omissing, int from);
bool proc_replica_info(int from, pg_info_t &info);
bool merge_old_entry(ObjectStore::Transaction& t, pg_log_entry_t& oe);
- void merge_log(ObjectStore::Transaction& t, pg_info_t &oinfo, Log &olog, int from);
+ void merge_log(ObjectStore::Transaction& t, pg_info_t &oinfo, pg_log_t &olog, int from);
bool search_for_missing(const pg_info_t &oinfo, const Missing *omissing,
int fromosd);
WRITE_CLASS_ENCODER(PG::Missing::item)
WRITE_CLASS_ENCODER(PG::Missing)
-WRITE_CLASS_ENCODER(PG::Log)
WRITE_CLASS_ENCODER(PG::Interval)
WRITE_CLASS_ENCODER(PG::OndiskLog)
-inline ostream& operator<<(ostream& out, const PG::Log& log)
-{
- out << "log(" << log.tail << "," << log.head << "]";
- return out;
-}
-
inline ostream& operator<<(ostream& out, const PG::Missing::item& i)
{
out << i.need;
}
+// -- pg_log_t --
+
+void pg_log_t::encode(bufferlist& bl) const
+{
+ __u8 struct_v = 2;
+ ::encode(struct_v, bl);
+ ::encode(head, bl);
+ ::encode(tail, bl);
+ ::encode(log, bl);
+}
+
+void pg_log_t::decode(bufferlist::iterator &bl)
+{
+ __u8 struct_v = 1;
+ ::decode(struct_v, bl);
+ ::decode(head, bl);
+ ::decode(tail, bl);
+ if (struct_v < 2) {
+ bool backlog;
+ ::decode(backlog, bl);
+ }
+ ::decode(log, bl);
+}
+
+void pg_log_t::dump(Formatter *f) const
+{
+ f->dump_stream("head") << head;
+ f->dump_stream("tail") << head;
+ f->open_array_section("log");
+ for (list<pg_log_entry_t>::const_iterator p = log.begin(); p != log.end(); ++p) {
+ f->open_object_section("entry");
+ p->dump(f);
+ f->close_section();
+ }
+ f->close_section();
+}
+
+void pg_log_t::generate_test_instances(list<pg_log_t*>& o)
+{
+ o.push_back(new pg_log_t);
+
+ // this is nonsensical:
+ o.push_back(new pg_log_t);
+ o.back()->head = eversion_t(1,2);
+ o.back()->tail = eversion_t(3,4);
+ list<pg_log_entry_t*> e;
+ pg_log_entry_t::generate_test_instances(e);
+ for (list<pg_log_entry_t*>::iterator p = e.begin(); p != e.end(); ++p)
+ o.back()->log.push_back(**p);
+}
+
+void pg_log_t::copy_after(const pg_log_t &other, eversion_t v)
+{
+ head = other.head;
+ tail = other.tail;
+ for (list<pg_log_entry_t>::const_reverse_iterator i = other.log.rbegin();
+ i != other.log.rend();
+ i++) {
+ assert(i->version > other.tail);
+ if (i->version <= v) {
+ // make tail accurate.
+ tail = i->version;
+ break;
+ }
+ log.push_front(*i);
+ }
+}
+
+void pg_log_t::copy_range(const pg_log_t &other, eversion_t from, eversion_t to)
+{
+ list<pg_log_entry_t>::const_reverse_iterator i = other.log.rbegin();
+ assert(i != other.log.rend());
+ while (i->version > to) {
+ ++i;
+ assert(i != other.log.rend());
+ }
+ assert(i->version == to);
+ head = to;
+ for ( ; i != other.log.rend(); ++i) {
+ if (i->version <= from) {
+ tail = i->version;
+ break;
+ }
+ log.push_front(*i);
+ }
+}
+
+void pg_log_t::copy_up_to(const pg_log_t &other, int max)
+{
+ int n = 0;
+ head = other.head;
+ tail = other.tail;
+ for (list<pg_log_entry_t>::const_reverse_iterator i = other.log.rbegin();
+ i != other.log.rend();
+ ++i) {
+ if (n++ >= max) {
+ tail = i->version;
+ break;
+ }
+ log.push_front(*i);
+ }
+}
+
+ostream& pg_log_t::print(ostream& out) const
+{
+ out << *this << std::endl;
+ for (list<pg_log_entry_t>::const_iterator p = log.begin();
+ p != log.end();
+ p++)
+ out << *p << std::endl;
+ return out;
+}
+
+
// -- OSDSuperblock --
void OSDSuperblock::encode(bufferlist &bl) const
+/**
+ * pg_log_t - incremental log of recent pg changes.
+ *
+ * serves as a recovery queue for recent changes.
+ */
+struct pg_log_t {
+ /*
+ * head - newest entry (update|delete)
+ * tail - entry previous to oldest (update|delete) for which we have
+ * complete negative information.
+ * i.e. we can infer pg contents for any store whose last_update >= tail.
+ */
+ eversion_t head; // newest entry
+ eversion_t tail; // version prior to oldest
+
+ list<pg_log_entry_t> log; // the actual log.
+
+ pg_log_t() {}
+
+ void clear() {
+ eversion_t z;
+ head = tail = z;
+ log.clear();
+ }
+
+ bool empty() const {
+ return log.empty();
+ }
+
+ bool null() const {
+ return head.version == 0 && head.epoch == 0;
+ }
+
+ size_t approx_size() const {
+ return head.version - tail.version;
+ }
+
+ list<pg_log_entry_t>::iterator find_entry(eversion_t v) {
+ int fromhead = head.version - v.version;
+ int fromtail = v.version - tail.version;
+ list<pg_log_entry_t>::iterator p;
+ if (fromhead < fromtail) {
+ p = log.end();
+ p--;
+ while (p->version > v)
+ p--;
+ return p;
+ } else {
+ p = log.begin();
+ while (p->version < v)
+ p++;
+ return p;
+ }
+ }
+
+ /**
+ * copy entries from the tail of another pg_log_t
+ *
+ * @param other pg_log_t to copy from
+ * @param from copy entries after this version
+ */
+ void copy_after(const pg_log_t &other, eversion_t from);
+
+ /**
+ * copy a range of entries from another pg_log_t
+ *
+ * @param other pg_log_t to copy from
+ * @param from copy entries after this version
+ * @parem to up to and including this version
+ */
+ void copy_range(const pg_log_t &other, eversion_t from, eversion_t to);
+
+ /**
+ * copy up to N entries
+ *
+ * @param o source log
+ * @param max max number of entreis to copy
+ */
+ void copy_up_to(const pg_log_t &other, int max);
+
+ ostream& print(ostream& out) const;
+
+ void encode(bufferlist &bl) const;
+ void decode(bufferlist::iterator &bl);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(list<pg_log_t*>& o);
+};
+WRITE_CLASS_ENCODER(pg_log_t)
+
+inline ostream& operator<<(ostream& out, const pg_log_t& log)
+{
+ out << "log(" << log.tail << "," << log.head << "]";
+ return out;
+}
+
+
struct osd_peer_stat_t {
TYPE(pg_info_t)
TYPE(pg_query_t)
TYPE(pg_log_entry_t)
+TYPE(pg_log_t)
TYPE(watch_info_t)
TYPE(object_info_t)