bool new_object;
int32_t max_num_intervals;
- /**
+ /**
* trim the number of intervals if clean_offsets.num_intervals()
* exceeds the given upbound max_num_intervals
* etc. max_num_intervals=2, clean_offsets:{[5~10], [20~5]}
return clean_offsets == orc.clean_offsets && clean_omap == orc.clean_omap && max_num_intervals == orc.max_num_intervals;
}
- void merge(const ObjectCleanRegions &other);
+ void merge(const ObjectCleanRegions &other);
void mark_data_region_dirty(uint64_t offset, uint64_t len);
void mark_omap_dirty();
void mark_object_new();
bool omap_is_dirty() const;
bool object_is_exist() const;
- void encode(bufferlist &bl) const;
+ void encode(bufferlist &bl) const;
void decode(bufferlist::const_iterator &bl);
void dump(Formatter *f) const;
static void generate_test_instances(list<ObjectCleanRegions*>& o);
__s32 op;
bool invalid_hash; // only when decoding sobject_t based entries
bool invalid_pool; // only when decoding pool-less hobject based entries
+ ObjectCleanRegions clean_regions;
pg_log_entry_t()
: user_version(0), return_code(0), op(0),
*/
struct pg_missing_item {
eversion_t need, have;
+ ObjectCleanRegions clean_regions;
enum missing_flags_t {
FLAG_NONE = 0,
FLAG_DELETE = 1,
} flags;
pg_missing_item() : flags(FLAG_NONE) {}
explicit pg_missing_item(eversion_t n) : need(n), flags(FLAG_NONE) {} // have no old version
- pg_missing_item(eversion_t n, eversion_t h, bool is_delete=false) : need(n), have(h) {
+ pg_missing_item(eversion_t n, eversion_t h, bool is_delete=false, bool old_style = false,bool new_object = false) :
+ need(n), have(h) {
+ if (old_style)
+ clean_regions.mark_fully_dirty();
+ if (new_object)
+ clean_regions.mark_object_new();
set_delete(is_delete);
}
void encode(ceph::buffer::list& bl, uint64_t features) const {
using ceph::encode;
- if (HAVE_FEATURE(features, OSD_RECOVERY_DELETES)) {
- // encoding a zeroed eversion_t to differentiate between this and
- // legacy unversioned encoding - a need value of 0'0 is not
- // possible. This can be replaced with the legacy encoding
- // macros post-luminous.
- eversion_t e;
- encode(e, bl);
- encode(need, bl);
- encode(have, bl);
+ // encoding a zeroed eversion_t to differentiate between OSD_RECOVERY_DELETES、
+ // SERVER_NAUTILUS and legacy unversioned encoding - a need value of 0'0 is not
+ // possible. This can be replaced with the legacy encoding
+
+ bool have_recovery_deletes = HAVE_FEATURE(features, OSD_RECOVERY_DELETES);
+ bool have_server_nautilus = HAVE_FEATURE(features, SERVER_NAUTILUS);
+
+ if (have_recovery_deletes)
+ encode(eversion_t(), bl);
+ if (have_server_nautilus)
+ encode(eversion_t(-1, -1), bl);
+
+ encode(need, bl);
+ encode(have, bl);
+
+ if (have_recovery_deletes)
encode(static_cast<uint8_t>(flags), bl);
- } else {
- // legacy unversioned encoding
- encode(need, bl);
- encode(have, bl);
- }
+ if (have_server_nautilus)
+ encode(clean_regions, bl);
}
void decode(ceph::buffer::list::const_iterator& bl) {
using ceph::decode;
eversion_t e;
decode(e, bl);
- if (e != eversion_t()) {
- // legacy encoding, this is the need value
- need = e;
+
+ if(e == eversion_t()) {
+ eversion_t l;
+ decode(l, bl);
+ if(l == eversion_t(-1, -1)) {
+ // support all
+ decode(need, bl);
+ decode(have, bl);
+ uint8_t f;
+ decode(f, bl);
+ flags = static_cast<missing_flags_t>(f);
+ decode(clean_regions, bl);
+ } else {
+ // support OSD_RECOVERY_DELETES
+ need = l;
+ decode(have, bl);
+ uint8_t f;
+ decode(f, bl);
+ flags = static_cast<missing_flags_t>(f);
+ }
+ } else if (e == eversion_t(-1, -1)) {
+ // support NAUTILUS
+ decode(need, bl);
decode(have, bl);
+ decode(clean_regions, bl);
} else {
- decode(need, bl);
+ // legacy encoding
+ need = e;
decode(have, bl);
- uint8_t f;
- decode(f, bl);
- flags = static_cast<missing_flags_t>(f);
}
}
f->dump_stream("need") << need;
f->dump_stream("have") << have;
f->dump_stream("flags") << flag_str();
+ f->dump_stream("clean_regions") << clean_regions;
}
static void generate_test_instances(std::list<pg_missing_item*>& o) {
o.push_back(new pg_missing_item);
o.push_back(new pg_missing_item);
o.back()->need = eversion_t(3, 5);
o.back()->have = eversion_t(3, 4);
+ o.back()->clean_regions.mark_data_region_dirty(4096, 8192);
+ o.back()->clean_regions.mark_omap_dirty();
o.back()->flags = FLAG_DELETE;
}
bool operator==(const pg_missing_item &rhs) const {
bool have_missing() const override {
return !missing.empty();
}
+ void merge(const pg_log_entry_t& e) {
+ auto miter = missing.find(e.soid);
+ if (miter != missing.end() && miter->second.have != eversion_t() && e.version > miter->second.have)
+ miter->second.clean_regions.merge(e.clean_regions);
+ }
bool is_missing(const hobject_t& oid, pg_missing_item *out = nullptr) const override {
auto iter = missing.find(oid);
if (iter == missing.end())
if (e.prior_version == eversion_t() || e.is_clone()) {
// new object.
if (is_missing_divergent_item) { // use iterator
- rmissing.erase((missing_it->second).need.version);
- missing_it->second = item(e.version, eversion_t(), e.is_delete()); // .have = nil
- } else // create new element in missing map
- missing[e.soid] = item(e.version, eversion_t(), e.is_delete()); // .have = nil
+ rmissing.erase((missing_it->second).need.version);
+ // .have = nil
+ missing_it->second = item(e.version, eversion_t(), e.is_delete());
+ missing_it->second.clean_regions.mark_fully_dirty();
+ } else {
+ // create new element in missing map
+ // .have = nil
+ missing[e.soid] = item(e.version, eversion_t(), e.is_delete());
+ missing[e.soid].clean_regions = e.clean_regions;
+ missing[e.soid].clean_regions.mark_fully_dirty();
+ }
} else if (is_missing_divergent_item) {
// already missing (prior).
rmissing.erase((missing_it->second).need.version);
(missing_it->second).need = e.version; // leave .have unchanged.
- missing_it->second.set_delete(e.is_delete());
+ (missing_it->second).set_delete(e.is_delete());
+ (missing_it->second).clean_regions.merge(e.clean_regions);
} else {
// not missing, we must have prior_version (if any)
ceph_assert(!is_missing_divergent_item);
missing[e.soid] = item(e.version, e.prior_version, e.is_delete());
+ missing[e.soid].clean_regions = e.clean_regions;
}
rmissing[e.version.version] = e.soid;
tracker.changed(e.soid);
}
void revise_need(hobject_t oid, eversion_t need, bool is_delete) {
- if (missing.count(oid)) {
- rmissing.erase(missing[oid].need.version);
- missing[oid].need = need; // no not adjust .have
- missing[oid].set_delete(is_delete);
+ auto p = missing.find(oid);
+ if (p != missing.end()) {
+ rmissing.erase((p->second).need.version);
+ (p->second).need = need; // no not adjust .have
+ (p->second).set_delete(is_delete);
+ (p->second).clean_regions.mark_fully_dirty();
} else {
missing[oid] = item(need, eversion_t(), is_delete);
+ missing[oid].clean_regions.mark_fully_dirty();
}
rmissing[need.version] = oid;
}
void revise_have(hobject_t oid, eversion_t have) {
- if (missing.count(oid)) {
+ auto p = missing.find(oid);
+ if (p != missing.end()) {
tracker.changed(oid);
- missing[oid].have = have;
+ (p->second).have = have;
}
}
void add(const hobject_t& oid, eversion_t need, eversion_t have,
- bool is_delete) {
- missing[oid] = item(need, have, is_delete);
+ bool is_delete, bool make_dirty = true) {
+ missing[oid] = item(need, have, is_delete, make_dirty, have == eversion_t());
rmissing[need.version] = oid;
tracker.changed(oid);
}
rmissing.clear();
}
- void encode(ceph::buffer::list &bl) const {
- ENCODE_START(4, 2, bl);
- encode(missing, bl, may_include_deletes ? CEPH_FEATURE_OSD_RECOVERY_DELETES : 0);
+ void encode(ceph::buffer::list &bl, uint64_t features) const {
+ ENCODE_START(5, 2, bl)
+ encode(missing, bl, features);
encode(may_include_deletes, bl);
ENCODE_FINISH(bl);
}
void decode(ceph::buffer::list::const_iterator &bl, int64_t pool = -1) {
for (auto const &i: missing)
tracker.changed(i.first);
- DECODE_START_LEGACY_COMPAT_LEN(4, 2, 2, bl);
+ DECODE_START_LEGACY_COMPAT_LEN(5, 2, 2, bl);
decode(missing, bl);
if (struct_v >= 4) {
decode(may_include_deletes, bl);
void encode(
const pg_missing_set<TrackChanges> &c, ceph::buffer::list &bl, uint64_t features=0) {
ENCODE_DUMP_PRE();
- c.encode(bl);
+ c.encode(bl, features);
ENCODE_DUMP_POST(cl);
}
template <bool TrackChanges>