extent_map.dump(f);
}
-
-const string& BlueStore::Onode::get_omap_prefix()
+const std::string& BlueStore::Onode::calc_omap_prefix(uint8_t flags)
{
- if (onode.is_pgmeta_omap()) {
+ if (bluestore_onode_t::is_pgmeta_omap(flags)) {
return PREFIX_PGMETA_OMAP;
}
- if (onode.is_perpool_omap()) {
+ if (bluestore_onode_t::is_perpool_omap(flags)) {
return PREFIX_PERPOOL_OMAP;
}
return PREFIX_OMAP;
}
// '-' < '.' < '~'
-
-void BlueStore::Onode::get_omap_header(string *out)
+void BlueStore::Onode::calc_omap_header(
+ uint8_t flags,
+ const Onode* o,
+ std::string* out)
{
- if (onode.is_perpool_omap() && !onode.is_pgmeta_omap()) {
- _key_encode_u64(c->pool(), out);
+ if (bluestore_onode_t::is_perpool_omap(flags) &&
+ !bluestore_onode_t::is_pgmeta_omap(flags)) {
+ _key_encode_u64(o->c->pool(), out);
}
- _key_encode_u64(onode.nid, out);
+ _key_encode_u64(o->onode.nid, out);
out->push_back('-');
}
-void BlueStore::Onode::get_omap_key(const string& key, string *out)
+void BlueStore::Onode::calc_omap_key(uint8_t flags,
+ const Onode* o,
+ const std::string& key,
+ std::string* out)
{
- if (onode.is_perpool_omap() && !onode.is_pgmeta_omap()) {
- _key_encode_u64(c->pool(), out);
+ if (bluestore_onode_t::is_perpool_omap(flags) &&
+ !bluestore_onode_t::is_pgmeta_omap(flags)) {
+ _key_encode_u64(o->c->pool(), out);
}
- _key_encode_u64(onode.nid, out);
+ _key_encode_u64(o->onode.nid, out);
out->push_back('.');
out->append(key);
}
out->append(old.c_str() + out->length(), old.size() - out->length());
}
-void BlueStore::Onode::get_omap_tail(string *out)
+void BlueStore::Onode::calc_omap_tail(
+ uint8_t flags,
+ const Onode* o,
+ std::string* out)
{
- if (onode.is_perpool_omap() && !onode.is_pgmeta_omap()) {
- _key_encode_u64(c->pool(), out);
+ if (bluestore_onode_t::is_perpool_omap(flags) &&
+ !bluestore_onode_t::is_pgmeta_omap(flags)) {
+ _key_encode_u64(o->c->pool(), out);
}
- _key_encode_u64(onode.nid, out);
+ _key_encode_u64(o->onode.nid, out);
out->push_back('~');
}
}
}
-
// =======================================================
// WriteContext
!o->onode.is_perpool_omap() &&
!o->onode.is_pgmeta_omap()) {
dout(10) << "fsck converting " << o->oid << " omap to per-pool" << dendl;
- bufferlist h;
- map<string, bufferlist> kv;
- int r = _onode_omap_get(o, &h, &kv);
- if (r < 0) {
- derr << " got " << r << " " << cpp_strerror(r) << dendl;
- } else {
+ bufferlist header;
+ {
+ KeyValueDB::Transaction txn = db->get_transaction();
+ uint64_t txn_cost = 0;
+ const string& prefix = Onode::calc_omap_prefix(o->onode.flags);
+ uint8_t new_flags = o->onode.flags |
+ bluestore_onode_t::FLAG_PERPOOL_OMAP;
+ const string& new_omap_prefix = Onode::calc_omap_prefix(new_flags);
+
+ KeyValueDB::Iterator it = db->get_iterator(prefix);
+ string head, tail;
+ o->get_omap_header(&head);
+ o->get_omap_tail(&tail);
+ it->lower_bound(head);
+ // head
+ if (it->valid() && it->key() == head) {
+ dout(30) << __func__ << " got header" << dendl;
+ header = it->value();
+ if (header.length()) {
+ string new_head;
+ Onode::calc_omap_header(new_flags, o.get(), &new_head);
+ txn->set(new_omap_prefix, new_head, header);
+ txn_cost += new_head.length() + header.length();
+ }
+ }
+ // tail
+ {
+ string new_tail;
+ Onode::calc_omap_tail(new_flags, o.get(), &new_tail);
+ bufferlist empty;
+ txn->set(new_omap_prefix, new_tail, empty);
+ txn_cost += new_tail.length() + new_tail.length();
+ }
+ // values
+ string final_key;
+ Onode::calc_omap_key(new_flags, o.get(), string(), &final_key);
+ size_t base_key_len = final_key.size();
+ while (it->valid() && it->key() < tail) {
+ string user_key;
+ o->decode_omap_key(it->key(), &user_key);
+ dout(20) << __func__ << " got " << pretty_binary_string(it->key())
+ << " -> " << user_key << dendl;
+
+ final_key.resize(base_key_len);
+ final_key += it->key();
+ auto v = it->value();
+ txn->set(new_omap_prefix, final_key, v);
+ txn_cost += final_key.length() + v.length();
+
+ // submit a portion if cost exceeds 16MB
+ if (txn_cost >= 16 * (1 << 20) ) {
+ db->submit_transaction_sync(txn);
+ txn = db->get_transaction();
+ txn_cost = 0;
+ }
+ it->next();
+ }
+ if (txn_cost > 0) {
+ db->submit_transaction_sync(txn);
+ }
+ }
+ // finalize: remove legacy data
+ {
KeyValueDB::Transaction txn = db->get_transaction();
// remove old keys
const string& old_omap_prefix = o->get_omap_prefix();
// set flag
o->onode.set_flag(bluestore_onode_t::FLAG_PERPOOL_OMAP);
_record_onode(o, txn);
- const string& new_omap_prefix = o->get_omap_prefix();
- // head
- if (h.length()) {
- string new_head;
- o->get_omap_header(&new_head);
- txn->set(new_omap_prefix, new_head, h);
- }
- // tail
- string new_tail;
- o->get_omap_tail(&new_tail);
- bufferlist empty;
- txn->set(new_omap_prefix, new_tail, empty);
- // values
- string final_key;
- o->get_omap_key(string(), &final_key);
- size_t base_key_len = final_key.size();
- for (auto& i : kv) {
- final_key.resize(base_key_len);
- final_key += i.first;
- txn->set(new_omap_prefix, final_key, i.second);
- }
db->submit_transaction_sync(txn);
repairer->inc_repaired();
repairer->request_compaction();
if (o->oid.is_pgmeta()) {
o->onode.set_omap_flags_pgmeta();
} else {
- o->onode.set_omap_flags();
+ o->onode.set_omap_flags(!per_pool_omap);
}
txc->write_onode(o);
if (o->oid.is_pgmeta()) {
o->onode.set_omap_flags_pgmeta();
} else {
- o->onode.set_omap_flags();
+ o->onode.set_omap_flags(!per_pool_omap);
}
txc->write_onode(o);
if (newo->oid.is_pgmeta()) {
newo->onode.set_omap_flags_pgmeta();
} else {
- newo->onode.set_omap_flags();
+ newo->onode.set_omap_flags(!per_pool_omap);
}
const string& prefix = newo->get_omap_prefix();
KeyValueDB::Iterator it = db->get_iterator(prefix);
return !pinned;
}
- const string& get_omap_prefix();
- void get_omap_header(string *out);
- void get_omap_key(const string& key, string *out);
+ static const std::string& calc_omap_prefix(uint8_t flags);
+ static void calc_omap_header(uint8_t flags, const Onode* o,
+ std::string* out);
+ static void calc_omap_key(uint8_t flags, const Onode* o,
+ const std::string& key, std::string* out);
+ static void calc_omap_tail(uint8_t flags, const Onode* o,
+ std::string* out);
+
+ const std::string& get_omap_prefix() {
+ return calc_omap_prefix(onode.flags);
+ }
+ void get_omap_header(std::string* out) {
+ calc_omap_header(onode.flags, this, out);
+ }
+ void get_omap_key(const std::string& key, std::string* out) {
+ calc_omap_key(onode.flags, this, key, out);
+ }
+ void get_omap_tail(std::string* out) {
+ calc_omap_tail(onode.flags, this, out);
+ }
void rewrite_omap_key(const string& old, string *out);
- void get_omap_tail(string *out);
void decode_omap_key(const string& key, string *user_key);
};
typedef boost::intrusive_ptr<Onode> OnodeRef;
void trim() {
std::lock_guard l(lock);
- _trim();
+ _trim();
}
void flush() {
std::lock_guard l(lock);