From 881669f00767198411cf040ead9eb44cca8be84a Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 18 Oct 2018 11:27:33 -0400 Subject: [PATCH] osd/PGLog: optionally record error return codes for extra_reqids When a cache tier promotes an object with one or more error PG log entries, these errors need to be propagated and recorded for dup op detection. Signed-off-by: Jason Dillaman --- src/osd/PGLog.cc | 12 +++++++++++- src/osd/PGLog.h | 9 ++++++++- src/osd/osd_types.cc | 15 ++++++++++++--- src/osd/osd_types.h | 4 ++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/osd/PGLog.cc b/src/osd/PGLog.cc index 1ed178b3cd3a7..ab9ead3fb924a 100644 --- a/src/osd/PGLog.cc +++ b/src/osd/PGLog.cc @@ -78,10 +78,20 @@ void PGLog::IndexedLog::trim( } dups.push_back(pg_log_dup_t(e)); index(dups.back()); + uint32_t idx = 0; for (const auto& extra : e.extra_reqids) { + int return_code = e.return_code; + if (return_code >= 0) { + auto it = e.extra_reqid_return_codes.find(idx); + if (it != e.extra_reqid_return_codes.end()) { + return_code = it->second; + } + } + ++idx; + // note: extras have the same version as outer op dups.push_back(pg_log_dup_t(e.version, extra.second, - extra.first, e.return_code)); + extra.first, return_code)); index(dups.back()); } } diff --git a/src/osd/PGLog.h b/src/osd/PGLog.h index 3b16e09ef5499..c7658ed26d275 100644 --- a/src/osd/PGLog.h +++ b/src/osd/PGLog.h @@ -289,13 +289,20 @@ public: } p = extra_caller_ops.find(r); if (p != extra_caller_ops.end()) { + uint32_t idx = 0; for (auto i = p->second->extra_reqids.begin(); i != p->second->extra_reqids.end(); - ++i) { + ++idx, ++i) { if (i->first == r) { *version = p->second->version; *user_version = i->second; *return_code = p->second->return_code; + if (*return_code >= 0) { + auto it = p->second->extra_reqid_return_codes.find(idx); + if (it != p->second->extra_reqid_return_codes.end()) { + *return_code = it->second; + } + } return true; } } diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index dc02c3ff11b9e..783d753edceb5 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -4022,7 +4022,7 @@ void pg_log_entry_t::decode_with_checksum(bufferlist::const_iterator& p) void pg_log_entry_t::encode(bufferlist &bl) const { - ENCODE_START(11, 4, bl); + ENCODE_START(12, 4, bl); encode(op, bl); encode(soid, bl); encode(version, bl); @@ -4049,12 +4049,14 @@ void pg_log_entry_t::encode(bufferlist &bl) const encode(extra_reqids, bl); if (op == ERROR) encode(return_code, bl); + if (!extra_reqids.empty()) + encode(extra_reqid_return_codes, bl); ENCODE_FINISH(bl); } void pg_log_entry_t::decode(bufferlist::const_iterator &bl) { - DECODE_START_LEGACY_COMPAT_LEN(11, 4, 4, bl); + DECODE_START_LEGACY_COMPAT_LEN(12, 4, 4, bl); decode(op, bl); if (struct_v < 2) { sobject_t old_soid; @@ -4108,6 +4110,8 @@ void pg_log_entry_t::decode(bufferlist::const_iterator &bl) decode(extra_reqids, bl); if (struct_v >= 11 && op == ERROR) decode(return_code, bl); + if (struct_v >= 12 && !extra_reqids.empty()) + decode(extra_reqid_return_codes, bl); DECODE_FINISH(bl); } @@ -4119,12 +4123,17 @@ void pg_log_entry_t::dump(Formatter *f) const f->dump_stream("prior_version") << prior_version; f->dump_stream("reqid") << reqid; f->open_array_section("extra_reqids"); + uint32_t idx = 0; for (auto p = extra_reqids.begin(); p != extra_reqids.end(); - ++p) { + ++idx, ++p) { f->open_object_section("extra_reqid"); f->dump_stream("reqid") << p->first; f->dump_stream("user_version") << p->second; + auto it = extra_reqid_return_codes.find(idx); + if (it != extra_reqid_return_codes.end()) { + f->dump_int("return_code", it->second); + } f->close_section(); } f->close_section(); diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index cd92a1c76a29f..448d811fcb11e 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -3485,6 +3485,10 @@ struct pg_log_entry_t { hobject_t soid; osd_reqid_t reqid; // caller+tid to uniquely identify request mempool::osd_pglog::vector > extra_reqids; + + ///< map extra_reqids by index to error return code (if any) + mempool::osd_pglog::map extra_reqid_return_codes; + eversion_t version, prior_version, reverting_to; version_t user_version; // the user version for this entry utime_t mtime; // this is the _user_ mtime, mind you -- 2.39.5