From 2fdd8087ceddf6f5e1fd8b7ca7893e7c2f62e7c2 Mon Sep 17 00:00:00 2001 From: Huisheng Liu Date: Tue, 7 Jan 2020 13:54:18 -0800 Subject: [PATCH] Implement getfreespace for WinEnv (#6265) Summary: A new interface method Env::GetFreeSpace was added in https://github.com/facebook/rocksdb/issues/4164. It needs to be implemented for Windows port. Some error_handler_test cases fail on Windows because recovery cannot succeed without free space being reported. Pull Request resolved: https://github.com/facebook/rocksdb/pull/6265 Differential Revision: D19303065 fbshipit-source-id: 1f1a83e53f334284781cf61feabc996e87b945ca --- port/win/env_win.cc | 18 ++++++++++++++++++ port/win/env_win.h | 12 ++++++++++++ port/win/port_win.h | 2 ++ 3 files changed, 32 insertions(+) diff --git a/port/win/env_win.cc b/port/win/env_win.cc index c12d0ee4f..b5ab1283b 100644 --- a/port/win/env_win.cc +++ b/port/win/env_win.cc @@ -1075,6 +1075,20 @@ std::string WinEnvIO::TimeToString(uint64_t secondsSince1970) { return result; } +Status WinEnvIO::GetFreeSpace(const std::string& path, uint64_t* diskfree) { + assert(diskfree != nullptr); + ULARGE_INTEGER freeBytes; + BOOL f = RX_GetDiskFreeSpaceEx(RX_FN(path).c_str(), &freeBytes, NULL, NULL); + if (f) { + *diskfree = freeBytes.QuadPart; + return Status::OK(); + } else { + DWORD lastError = GetLastError(); + return IOErrorFromWindowsError("Failed to get free space: " + path, + lastError); + } +} + EnvOptions WinEnvIO::OptimizeForLogWrite(const EnvOptions& env_options, const DBOptions& db_options) const { EnvOptions optimized(env_options); @@ -1467,6 +1481,10 @@ uint64_t WinEnv::GetThreadID() const { return winenv_threads_.GetThreadID(); } +Status WinEnv::GetFreeSpace(const std::string& path, uint64_t* diskfree) { + return winenv_io_.GetFreeSpace(path, diskfree); +} + void WinEnv::SleepForMicroseconds(int micros) { return winenv_threads_.SleepForMicroseconds(micros); } diff --git a/port/win/env_win.h b/port/win/env_win.h index 7a4d48de2..49e1c4cb1 100644 --- a/port/win/env_win.h +++ b/port/win/env_win.h @@ -164,6 +164,12 @@ public: virtual Status GetAbsolutePath(const std::string& db_path, std::string* output_path); + // This seems to clash with a macro on Windows, so #undef it here +#undef GetFreeSpace + + // Get the amount of free disk space + virtual Status GetFreeSpace(const std::string& path, uint64_t* diskfree); + virtual std::string TimeToString(uint64_t secondsSince1970); virtual EnvOptions OptimizeForLogWrite(const EnvOptions& env_options, @@ -307,6 +313,12 @@ public: uint64_t GetThreadID() const override; + // This seems to clash with a macro on Windows, so #undef it here +#undef GetFreeSpace + + // Get the amount of free disk space + Status GetFreeSpace(const std::string& path, uint64_t* diskfree) override; + void SleepForMicroseconds(int micros) override; // Allow increasing the number of worker threads. diff --git a/port/win/port_win.h b/port/win/port_win.h index 1b302b3d2..6f16b9c23 100644 --- a/port/win/port_win.h +++ b/port/win/port_win.h @@ -363,6 +363,7 @@ std::wstring utf8_to_utf16(const std::string& utf8); #define RX_CreateHardLink CreateHardLinkW #define RX_PathIsRelative PathIsRelativeW #define RX_GetCurrentDirectory GetCurrentDirectoryW +#define RX_GetDiskFreeSpaceEx GetDiskFreeSpaceExW #else @@ -386,6 +387,7 @@ std::wstring utf8_to_utf16(const std::string& utf8); #define RX_CreateHardLink CreateHardLinkA #define RX_PathIsRelative PathIsRelativeA #define RX_GetCurrentDirectory GetCurrentDirectoryA +#define RX_GetDiskFreeSpaceEx GetDiskFreeSpaceExA #endif