From: Mark Nelson Date: Fri, 7 Dec 2018 19:02:52 +0000 (-0600) Subject: kv/rocksdb_cache: Remove C style struct hack undefined behavior X-Git-Tag: v14.1.0~572^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=89a75259fecd18a14701c61ba27f39d8059a2337;p=ceph-ci.git kv/rocksdb_cache: Remove C style struct hack undefined behavior Signed-off-by: Mark Nelson --- diff --git a/src/kv/rocksdb_cache/BinnedLRUCache.cc b/src/kv/rocksdb_cache/BinnedLRUCache.cc index 217f0c1dcff..91ed1185ec9 100644 --- a/src/kv/rocksdb_cache/BinnedLRUCache.cc +++ b/src/kv/rocksdb_cache/BinnedLRUCache.cc @@ -342,11 +342,7 @@ rocksdb::Status BinnedLRUCacheShard::Insert(const rocksdb::Slice& key, uint32_t size_t charge, void (*deleter)(const rocksdb::Slice& key, void* value), rocksdb::Cache::Handle** handle, rocksdb::Cache::Priority priority) { - // Allocate the memory here outside of the mutex - // If the cache is full, we'll have to release it - // It shouldn't happen very often though. - BinnedLRUHandle* e = reinterpret_cast( - new char[sizeof(BinnedLRUHandle) - 1 + key.size()]); + auto e = new BinnedLRUHandle(); rocksdb::Status s; ceph::autovector last_reference_list; @@ -354,6 +350,7 @@ rocksdb::Status BinnedLRUCacheShard::Insert(const rocksdb::Slice& key, uint32_t e->deleter = deleter; e->charge = charge; e->key_length = key.size(); + e->key_data = new char[e->key_length]; e->flags = 0; e->hash = hash; e->refs = (handle == nullptr @@ -362,7 +359,7 @@ rocksdb::Status BinnedLRUCacheShard::Insert(const rocksdb::Slice& key, uint32_t e->next = e->prev = nullptr; e->SetInCache(true); e->SetPriority(priority); - memcpy(e->key_data, key.data(), key.size()); + std::copy_n(key.data(), e->key_length, e->key_data); { std::lock_guard l(mutex_); @@ -377,7 +374,7 @@ rocksdb::Status BinnedLRUCacheShard::Insert(const rocksdb::Slice& key, uint32_t // into cache and get evicted immediately. last_reference_list.push_back(e); } else { - delete[] reinterpret_cast(e); + delete e; *handle = nullptr; s = rocksdb::Status::Incomplete("Insert failed due to LRU cache being full."); } diff --git a/src/kv/rocksdb_cache/BinnedLRUCache.h b/src/kv/rocksdb_cache/BinnedLRUCache.h index 17f91723037..d48286a1dab 100644 --- a/src/kv/rocksdb_cache/BinnedLRUCache.h +++ b/src/kv/rocksdb_cache/BinnedLRUCache.h @@ -71,7 +71,7 @@ struct BinnedLRUHandle { uint32_t hash; // Hash of key(); used for fast sharding and comparisons - char key_data[1]; // Beginning of key + char* key_data = nullptr; // Beginning of key rocksdb::Slice key() const { // For cheaper lookups, we allow a temporary Handle object @@ -119,7 +119,8 @@ struct BinnedLRUHandle { if (deleter) { (*deleter)(key(), value); } - delete[] reinterpret_cast(this); + delete[] key_data; + delete this; } };