From 4d310a8249d64d9aadd7fdfeacbeda826501b0f0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 29 Jan 2015 11:26:23 -0800 Subject: [PATCH] osd: preserve extra_reqids in PGLog The log scraping is unfortunately O(n) in the size of the log. We can also follow objects and then the prior_version pointers, but we don't have a version->entry index at the moment. Only index by reqid if reqid_is_index. Always index extra_reqids. Notably, the PROMOTE op does not return true for reqid_is_indexed, but this is where the promotion extra_reqids will appear. Signed-off-by: Sage Weil --- src/osd/PGLog.h | 72 ++++++++++++++++++++++++++++---------------- src/osd/osd_types.cc | 15 +++++++-- src/osd/osd_types.h | 4 +++ 3 files changed, 63 insertions(+), 28 deletions(-) diff --git a/src/osd/PGLog.h b/src/osd/PGLog.h index 55e90ec8775..d0b74d42db3 100644 --- a/src/osd/PGLog.h +++ b/src/osd/PGLog.h @@ -139,6 +139,26 @@ struct PGLog { return NULL; } + /// get a (bounded) list of recent reqids for the given object + void get_object_reqids(const hobject_t& oid, unsigned max, + vector *pls) const { + for (list::const_reverse_iterator i = log.rbegin(); + i != log.rend(); + ++i) { + if (i->soid == oid) { + if (i->reqid_is_indexed()) + pls->push_back(i->reqid); + pls->insert(pls->end(), i->extra_reqids.begin(), i->extra_reqids.end()); + if (pls->size() >= max) { + if (pls->size() > max) { + pls->resize(max); + } + return; + } + } + } + } + void index() { objects.clear(); caller_ops.clear(); @@ -150,11 +170,11 @@ struct PGLog { if (i->reqid_is_indexed()) { //assert(caller_ops.count(i->reqid) == 0); // divergent merge_log indexes new before unindexing old caller_ops[i->reqid] = &(*i); - for (vector::const_iterator j = i->extra_reqids.begin(); - j != i->extra_reqids.end(); - ++j) { - extra_caller_ops.insert(make_pair(*j, &(*i))); - } + } + for (vector::const_iterator j = i->extra_reqids.begin(); + j != i->extra_reqids.end(); + ++j) { + extra_caller_ops.insert(make_pair(*j, &(*i))); } } @@ -171,11 +191,11 @@ struct PGLog { if (e.reqid_is_indexed()) { //assert(caller_ops.count(i->reqid) == 0); // divergent merge_log indexes new before unindexing old caller_ops[e.reqid] = &e; - for (vector::const_iterator j = e.extra_reqids.begin(); - j != e.extra_reqids.end(); - ++j) { - extra_caller_ops.insert(make_pair(*j, &e)); - } + } + for (vector::const_iterator j = e.extra_reqids.begin(); + j != e.extra_reqids.end(); + ++j) { + extra_caller_ops.insert(make_pair(*j, &e)); } } void unindex() { @@ -191,17 +211,17 @@ struct PGLog { if (caller_ops.count(e.reqid) && // divergent merge_log indexes new before unindexing old caller_ops[e.reqid] == &e) caller_ops.erase(e.reqid); - for (vector::const_iterator j = e.extra_reqids.begin(); - j != e.extra_reqids.end(); - ++j) { - for (ceph::unordered_multimap::iterator k = - extra_caller_ops.find(*j); - k != extra_caller_ops.end() && k->first == *j; - ++j) { - if (k->second == &e) { - extra_caller_ops.erase(k); - break; - } + } + for (vector::const_iterator j = e.extra_reqids.begin(); + j != e.extra_reqids.end(); + ++j) { + for (ceph::unordered_multimap::iterator k = + extra_caller_ops.find(*j); + k != extra_caller_ops.end() && k->first == *j; + ++k) { + if (k->second == &e) { + extra_caller_ops.erase(k); + break; } } } @@ -224,11 +244,11 @@ struct PGLog { objects[e.soid] = &(log.back()); if (e.reqid_is_indexed()) { caller_ops[e.reqid] = &(log.back()); - for (vector::const_iterator j = e.extra_reqids.begin(); - j != e.extra_reqids.end(); - ++j) { - extra_caller_ops.insert(make_pair(*j, &(log.back()))); - } + } + for (vector::const_iterator j = e.extra_reqids.begin(); + j != e.extra_reqids.end(); + ++j) { + extra_caller_ops.insert(make_pair(*j, &(log.back()))); } } diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index ab4253833c2..92ffb669c09 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -3450,7 +3450,7 @@ void object_copy_data_t::encode(bufferlist& bl, uint64_t features) const return; } - ENCODE_START(5, 5, bl); + ENCODE_START(6, 5, bl); ::encode(size, bl); ::encode(mtime, bl); ::encode(attrs, bl); @@ -3463,12 +3463,13 @@ void object_copy_data_t::encode(bufferlist& bl, uint64_t features) const ::encode(flags, bl); ::encode(data_digest, bl); ::encode(omap_digest, bl); + ::encode(reqids, bl); ENCODE_FINISH(bl); } void object_copy_data_t::decode(bufferlist::iterator& bl) { - DECODE_START(5, bl); + DECODE_START(6, bl); if (struct_v < 5) { // old ::decode(size, bl); @@ -3523,6 +3524,9 @@ void object_copy_data_t::decode(bufferlist::iterator& bl) ::decode(data_digest, bl); ::decode(omap_digest, bl); } + if (struct_v >= 6) { + ::decode(reqids, bl); + } } DECODE_FINISH(bl); } @@ -3556,6 +3560,7 @@ void object_copy_data_t::generate_test_instances(list& o) o.back()->data.push_back(databp); o.back()->omap_header.append("this is an omap header"); o.back()->snaps.push_back(123); + o.back()->reqids.push_back(osd_reqid_t()); } void object_copy_data_t::dump(Formatter *f) const @@ -3579,6 +3584,12 @@ void object_copy_data_t::dump(Formatter *f) const p != snaps.end(); ++p) f->dump_unsigned("snap", *p); f->close_section(); + f->open_array_section("reqids"); + for (vector::const_iterator p = reqids.begin(); + p != reqids.end(); + ++p) + f->dump_stream("reqid") << *p; + f->close_section(); } // -- pg_create_t -- diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index 979e69f182c..5fdb17bb248 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -2564,6 +2564,10 @@ struct object_copy_data_t { vector snaps; ///< latest snap seq for the object (if head) snapid_t snap_seq; + + ///< recent reqids on this object + vector reqids; + public: object_copy_data_t() : size((uint64_t)-1), data_digest(-1), omap_digest(-1), flags(0) {}