osd: define ObjectCleanRegions for recovery object

Signed-off-by: Ning Yao <yaoning@unitedstack.com>
Signed-off-by: lishuhao <lishuhao@unitedstack.com>
This commit is contained in:
lishuhao 2019-04-14 08:36:24 +08:00 committed by letterwuyu
parent 20e26e8395
commit 3a8164ac35
2 changed files with 159 additions and 0 deletions

View File

@ -4275,6 +4275,118 @@ void ObjectModDesc::decode(ceph::buffer::list::const_iterator &_bl)
DECODE_FINISH(_bl);
}
void ObjectCleanRegions::trim()
{
while(clean_offsets.num_intervals() > max_num_intervals) {
typename interval_set<uint64_t>::iterator shortest_interval = clean_offsets.begin();
if (shortest_interval == clean_offsets.end())
break;
for (typename interval_set<uint64_t>::iterator it = clean_offsets.begin();
it != clean_offsets.end();
++it) {
if (it.get_len() < shortest_interval.get_len())
shortest_interval = it;
}
clean_offsets.erase(shortest_interval);
}
}
void ObjectCleanRegions::merge(const ObjectCleanRegions &other)
{
clean_offsets.intersection_of(other.clean_offsets);
clean_omap = clean_omap && other.clean_omap;
trim();
}
void ObjectCleanRegions::mark_data_region_dirty(uint64_t offset, uint64_t len)
{
interval_set<uint64_t> clean_region;
clean_region.insert(0, (uint64_t)-1);
clean_region.erase(offset, len);
clean_offsets.intersection_of(clean_region);
trim();
}
void ObjectCleanRegions::mark_omap_dirty()
{
clean_omap = false;
}
void ObjectCleanRegions::mark_object_new()
{
new_object = true;
}
void ObjectCleanRegions::mark_fully_dirty()
{
mark_data_region_dirty(0, (uint64_t)-1);
mark_omap_dirty();
mark_object_new();
}
interval_set<uint64_t> ObjectCleanRegions::get_dirty_regions() const
{
interval_set<uint64_t> dirty_region;
dirty_region.insert(0, (uint64_t)-1);
dirty_region.subtract(clean_offsets);
return dirty_region;
}
bool ObjectCleanRegions::omap_is_dirty() const
{
return !clean_omap;
}
bool ObjectCleanRegions::object_is_exist() const
{
return !new_object;
}
void ObjectCleanRegions::encode(bufferlist &bl) const
{
ENCODE_START(1, 1, bl);
using ceph::encode;
encode(clean_offsets, bl);
encode(clean_omap, bl);
encode(new_object, bl);
ENCODE_FINISH(bl);
}
void ObjectCleanRegions::decode(bufferlist::const_iterator &bl)
{
DECODE_START(1, bl);
using ceph::decode;
decode(clean_offsets, bl);
decode(clean_omap, bl);
decode(new_object, bl);
DECODE_FINISH(bl);
}
void ObjectCleanRegions::dump(Formatter *f) const
{
f->open_object_section("object_clean_regions");
f->dump_stream("clean_offsets") << clean_offsets;
f->dump_bool("clean_omap", clean_omap);
f->dump_bool("object_new", new_object);
f->close_section();
}
void ObjectCleanRegions::generate_test_instances(list<ObjectCleanRegions*>& o)
{
o.push_back(new ObjectCleanRegions());
o.push_back(new ObjectCleanRegions());
o.back()->mark_data_region_dirty(4096, 40960);
o.back()->mark_omap_dirty();
o.back()->mark_object_new();
}
ostream& operator<<(ostream& out, const ObjectCleanRegions& ocr)
{
return out << "clean_offsets: " << ocr.clean_offsets
<< ", clean_omap: " << ocr.clean_omap
<< ", object_new: " << ocr.new_object;
}
// -- pg_log_entry_t --
string pg_log_entry_t::get_key_name() const

View File

@ -108,6 +108,8 @@
/// priority when more full
#define OSD_DELETE_PRIORITY_FULL 255
/// max intervals for clean_offsets in ObjectCleanRegions
#define OSD_CLEAN_OFFSETS_MAX_INTERVALS 10
static std::map<int, int> max_prio_map = {
{OSD_BACKFILL_PRIORITY_BASE, OSD_BACKFILL_DEGRADED_PRIORITY_BASE - 1},
{OSD_BACKFILL_DEGRADED_PRIORITY_BASE, OSD_RECOVERY_PRIORITY_BASE - 1},
@ -3744,6 +3746,51 @@ public:
};
WRITE_CLASS_ENCODER(ObjectModDesc)
class ObjectCleanRegions {
private:
interval_set<uint64_t> clean_offsets;
bool clean_omap;
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]}
* then new interval [30~10] will evict out the shortest one [20~5]
* finally, clean_offsets becomes {[5~10], [30~10]}
*/
void trim();
friend ostream& operator<<(ostream& out, const ObjectCleanRegions& ocr);
public:
ObjectCleanRegions(int32_t max = OSD_CLEAN_OFFSETS_MAX_INTERVALS) : new_object(false), max_num_intervals(max) {
clean_offsets.insert(0, (uint64_t)-1);
clean_omap = true;
}
ObjectCleanRegions(uint64_t offset, uint64_t len, bool co, int32_t max = OSD_CLEAN_OFFSETS_MAX_INTERVALS)
: clean_omap(co), new_object(false), max_num_intervals(max) {
clean_offsets.insert(offset, len);
}
bool operator==(const ObjectCleanRegions &orc) const {
return clean_offsets == orc.clean_offsets && clean_omap == orc.clean_omap && max_num_intervals == orc.max_num_intervals;
}
void merge(const ObjectCleanRegions &other);
void mark_data_region_dirty(uint64_t offset, uint64_t len);
void mark_omap_dirty();
void mark_object_new();
void mark_fully_dirty();
interval_set<uint64_t> get_dirty_regions() const;
bool omap_is_dirty() const;
bool object_is_exist() 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);
};
WRITE_CLASS_ENCODER(ObjectCleanRegions)
ostream& operator<<(ostream& out, const ObjectCleanRegions& ocr);
/**
* pg_log_entry_t - single entry/event in pg log