diff --git a/db/db_test_util.h b/db/db_test_util.h index 53e6c506f8e..1fc8952a436 100644 --- a/db/db_test_util.h +++ b/db/db_test_util.h @@ -85,9 +85,6 @@ class TestKeyManager : public encryption::KeyManager { Status LinkFile(const std::string&, const std::string&) override { return Status::OK(); } - Status RenameFile(const std::string&, const std::string&) override { - return Status::OK(); - } }; #endif diff --git a/encryption/encryption.cc b/encryption/encryption.cc index 435022766fb..a7e012fc37b 100644 --- a/encryption/encryption.cc +++ b/encryption/encryption.cc @@ -4,11 +4,11 @@ #ifdef OPENSSL #include "encryption/encryption.h" +#include + #include #include -#include - #include "port/port.h" namespace rocksdb { @@ -372,9 +372,14 @@ Status KeyManagedEncryptedEnv::ReuseWritableFile( s = Status::InvalidArgument("Unsupported encryption method: " + ToString(static_cast(file_info.method))); } - if (s.ok()) { - s = key_manager_->RenameFile(old_fname, fname); + if (!s.ok()) { + return s; + } + s = key_manager_->LinkFile(old_fname, fname); + if (!s.ok()) { + return s; } + s = key_manager_->DeleteFile(old_fname); return s; } @@ -426,22 +431,28 @@ Status KeyManagedEncryptedEnv::LinkFile(const std::string& src_fname, } s = target()->LinkFile(src_fname, dst_fname); if (!s.ok()) { - // Ignore error - key_manager_->DeleteFile(dst_fname); + Status delete_status __attribute__((__unused__)) = + key_manager_->DeleteFile(dst_fname); + assert(delete_status.ok()); } return s; } Status KeyManagedEncryptedEnv::RenameFile(const std::string& src_fname, const std::string& dst_fname) { - Status s = key_manager_->RenameFile(src_fname, dst_fname); + // Link(copy)File instead of RenameFile to avoid losing src_fname info when + // failed to rename the src_fname in the file system. + Status s = key_manager_->LinkFile(src_fname, dst_fname); if (!s.ok()) { return s; } s = target()->RenameFile(src_fname, dst_fname); - if (!s.ok()) { - // Ignore error - key_manager_->RenameFile(dst_fname, src_fname); + if (s.ok()) { + s = key_manager_->DeleteFile(src_fname); + } else { + Status delete_status __attribute__((__unused__)) = + key_manager_->DeleteFile(dst_fname); + assert(delete_status.ok()); } return s; } diff --git a/encryption/in_memory_key_manager.h b/encryption/in_memory_key_manager.h index f93bf985989..ae8e3de3fdc 100644 --- a/encryption/in_memory_key_manager.h +++ b/encryption/in_memory_key_manager.h @@ -71,17 +71,6 @@ class InMemoryKeyManager final : public KeyManager { return Status::OK(); } - Status RenameFile(const std::string& src_fname, - const std::string& dst_fname) override { - MutexLock l(&mu_); - if (files_.count(src_fname) == 0) { - return Status::Corruption("File not found: " + src_fname); - } - files_[dst_fname] = files_[src_fname]; - files_.erase(src_fname); - return Status::OK(); - } - private: mutable port::Mutex mu_; Random rnd_; diff --git a/include/rocksdb/encryption.h b/include/rocksdb/encryption.h index 88d0238b5dd..c65e02e8810 100644 --- a/include/rocksdb/encryption.h +++ b/include/rocksdb/encryption.h @@ -55,8 +55,6 @@ class KeyManager { virtual Status DeleteFile(const std::string& fname) = 0; virtual Status LinkFile(const std::string& src_fname, const std::string& dst_fname) = 0; - virtual Status RenameFile(const std::string& src_fname, - const std::string& dst_fname) = 0; }; // An Env with underlying files being encrypted. It holds a reference to an