]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
os/bluestore: make fsck repair convert to per-pool omap
authorSage Weil <sage@redhat.com>
Tue, 30 Jul 2019 00:43:53 +0000 (19:43 -0500)
committerSage Weil <sage@redhat.com>
Thu, 8 Aug 2019 22:26:24 +0000 (17:26 -0500)
- error if objects not per-pool
- error if per_pool_omap not set
- convert as we go, and set the flag at the end

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index 4ce2d3781896583ec9cd9a642a190b1e838ae0ed..c6f90c937193cf5c66edf432f97abfce7a5247cc 100644 (file)
@@ -7164,6 +7164,14 @@ int BlueStore::_fsck(bool deep, bool repair)
       errors += r;
   }
 
+  if (!per_pool_omap) {
+    derr << "fsck error: store not yet converted to per-pool omap" << dendl;
+    ++errors;
+    if (repair) {
+      repairer.fix_per_pool_omap(db);
+    }
+  }
+
   // get expected statfs; reset unaffected fields to be able to compare
   // structs
   statfs(&actual_statfs);
@@ -7493,6 +7501,61 @@ int BlueStore::_fsck(bool deep, bool repair)
        } else {
          m.insert(o->onode.nid);
        }
+       if (per_pool_omap &&
+           (!o->onode.is_perpool_omap() && !o->onode.is_pgmeta_omap())) {
+         derr << "fsck error: " << oid << " has omap that is not per-pool or pgmeta"
+              << dendl;
+         ++errors;
+       }
+       if (repair &&
+           o->onode.has_omap() &&
+           !o->onode.is_perpool_omap() &&
+           !o->oid.is_pgmeta()) {
+         derr << "fsck converting " << oid << " omap to per-pool" << dendl;
+         used_omap_head.erase(o->onode.nid);
+         used_per_pool_omap_head.insert(o->onode.nid);
+         bufferlist h;
+         map<string,bufferlist> kv;
+         int r = _omap_get(c.get(), oid, &h, &kv);
+         if (r < 0) {
+           derr << " got " << r << " " << cpp_strerror(r) << dendl;
+         } else {
+           KeyValueDB::Transaction txn = db->get_transaction();
+           // remove old keys
+           const string& old_omap_prefix = o->get_omap_prefix();
+           string old_head, old_tail;
+           o->get_omap_header(&old_head);
+           o->get_omap_tail(&old_tail);
+           txn->rm_range_keys(old_omap_prefix, old_head, old_tail);
+           txn->rmkey(old_omap_prefix, old_tail);
+           // 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();
+         }
+       }
       }
       expected_statfs->add(onode_statfs);
     } // for (it->lower_bound(string()); it->valid(); it->next())
@@ -7846,7 +7909,7 @@ int BlueStore::_fsck(bool deep, bool repair)
       uint64_t pool;
       uint64_t omap_head;
       string k = it->key();
-      char *c = k.c_str();
+      const char *c = k.c_str();
       c = _key_decode_u64(c, &pool);
       c = _key_decode_u64(c, &omap_head);
       if (used_per_pool_omap_head.count(omap_head) == 0) {
@@ -9489,6 +9552,16 @@ int BlueStore::omap_get(
   )
 {
   Collection *c = static_cast<Collection *>(c_.get());
+  return _omap_get(c, oid, header, out);
+}
+
+int BlueStore::_omap_get(
+  Collection *c,    ///< [in] Collection containing oid
+  const ghobject_t &oid,   ///< [in] Object containing omap
+  bufferlist *header,      ///< [out] omap header
+  map<string, bufferlist> *out /// < [out] Key to value map
+  )
+{
   dout(15) << __func__ << " " << c->get_cid() << " oid " << oid << dendl;
   if (!c->exists)
     return -ENOENT;
@@ -14222,6 +14295,15 @@ bool BlueStoreRepairer::remove_key(KeyValueDB *db,
   return true;
 }
 
+void BlueStoreRepairer::fix_per_pool_omap(KeyValueDB *db)
+{
+  fix_per_pool_omap_txn = db->get_transaction();
+  ++to_repair_cnt;
+  bufferlist bl;
+  bl.append("1");
+  fix_per_pool_omap_txn->set(PREFIX_SUPER, "per_pool_omap", bl);
+}
+
 bool BlueStoreRepairer::fix_shared_blob(
   KeyValueDB *db,
   uint64_t sbid,
@@ -14312,6 +14394,10 @@ bool BlueStoreRepairer::preprocess_misreference(KeyValueDB *db)
 
 unsigned BlueStoreRepairer::apply(KeyValueDB* db)
 {
+  if (fix_per_pool_omap_txn) {
+    db->submit_transaction_sync(fix_per_pool_omap_txn);
+    fix_per_pool_omap_txn = nullptr;
+  }
   if (fix_fm_leaked_txn) {
     db->submit_transaction_sync(fix_fm_leaked_txn);
     fix_fm_leaked_txn = nullptr;
index 18847f5a213617b223657da89185c24cc1af47a7..da6725f5ad4e79c8607bfbd216ec2c07d44d14a5 100644 (file)
@@ -2444,6 +2444,12 @@ public:
     bufferlist *header,      ///< [out] omap header
     map<string, bufferlist> *out /// < [out] Key to value map
     ) override;
+  int _omap_get(
+    Collection *c,     ///< [in] Collection containing oid
+    const ghobject_t &oid,   ///< [in] Object containing omap
+    bufferlist *header,      ///< [out] omap header
+    map<string, bufferlist> *out /// < [out] Key to value map
+    );
 
   /// Get omap header
   int omap_get_header(
@@ -3069,7 +3075,7 @@ public:
     }
   };
 public:
-
+  void fix_per_pool_omap(KeyValueDB *db);
   bool remove_key(KeyValueDB *db, const string& prefix, const string& key);
   bool fix_shared_blob(KeyValueDB *db,
                         uint64_t sbid,
@@ -3097,6 +3103,9 @@ public:
       ++to_repair_cnt;
     }
   }
+  void inc_repaired() {
+    ++to_repair_cnt;
+  }
 
   StoreSpaceTracker& get_space_usage_tracker() {
     return space_usage_tracker;
@@ -3110,6 +3119,7 @@ public:
 
 private:
   unsigned to_repair_cnt = 0;
+  KeyValueDB::Transaction fix_per_pool_omap_txn;
   KeyValueDB::Transaction fix_fm_leaked_txn;
   KeyValueDB::Transaction fix_fm_false_free_txn;
   KeyValueDB::Transaction remove_key_txn;