aboutsummaryrefslogtreecommitdiff
path: root/zenstore
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2021-12-14 12:34:47 +0100
committerPer Larsson <[email protected]>2021-12-14 12:34:47 +0100
commitb6c6568e1618f10d2160d836b65e35586e3c740f (patch)
treef6a929cf918850bbba87d0ee67cd3482b2d50e24 /zenstore
parentFixed bug in z$ service returning partial cache records and enable small obje... (diff)
parentPartial revert b363c5b (diff)
downloadzen-b6c6568e1618f10d2160d836b65e35586e3c740f.tar.xz
zen-b6c6568e1618f10d2160d836b65e35586e3c740f.zip
Merged main.
Diffstat (limited to 'zenstore')
-rw-r--r--zenstore/basicfile.cpp86
-rw-r--r--zenstore/cas.cpp (renamed from zenstore/CAS.cpp)0
-rw-r--r--zenstore/caslog.cpp6
-rw-r--r--zenstore/cidstore.cpp2
-rw-r--r--zenstore/compactcas.cpp2
-rw-r--r--zenstore/compactcas.h5
-rw-r--r--zenstore/filecas.cpp129
-rw-r--r--zenstore/filecas.h6
-rw-r--r--zenstore/gc.cpp2
-rw-r--r--zenstore/include/zenstore/basicfile.h1
-rw-r--r--zenstore/include/zenstore/cas.h (renamed from zenstore/include/zenstore/CAS.h)6
-rw-r--r--zenstore/include/zenstore/caslog.h5
-rw-r--r--zenstore/include/zenstore/cidstore.h2
-rw-r--r--zenstore/zenstore.cpp2
-rw-r--r--zenstore/zenstore.vcxproj2
-rw-r--r--zenstore/zenstore.vcxproj.filters2
16 files changed, 225 insertions, 33 deletions
diff --git a/zenstore/basicfile.cpp b/zenstore/basicfile.cpp
index 9ed70a5ec..80d9a2204 100644
--- a/zenstore/basicfile.cpp
+++ b/zenstore/basicfile.cpp
@@ -9,6 +9,14 @@
#include <zencore/testing.h>
#include <zencore/testutils.h>
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+#else
+# include <fcntl.h>
+# include <sys/file.h>
+# include <sys/stat.h>
+#endif
+
#include <fmt/format.h>
#include <gsl/gsl-lite.hpp>
@@ -38,6 +46,7 @@ BasicFile::Open(std::filesystem::path FileName, bool IsCreate, std::error_code&
{
Ec.clear();
+#if ZEN_PLATFORM_WINDOWS
const DWORD dwCreationDisposition = IsCreate ? CREATE_ALWAYS : OPEN_EXISTING;
DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
const DWORD dwShareMode = FILE_SHARE_READ;
@@ -63,6 +72,19 @@ BasicFile::Open(std::filesystem::path FileName, bool IsCreate, std::error_code&
return;
}
+#else
+ int OpenFlags = O_RDWR;
+ OpenFlags |= IsCreate ? O_CREAT | O_TRUNC : 0;
+
+ int Fd = open(FileName.c_str(), OpenFlags, 0666);
+ if (Fd < 0)
+ {
+ Ec = zen::MakeErrorCodeFromLastError();
+ return;
+ }
+
+ void* FileHandle = (void*)(uintptr_t(Fd));
+#endif
m_FileHandle = FileHandle;
}
@@ -72,7 +94,12 @@ BasicFile::Close()
{
if (m_FileHandle)
{
+#if ZEN_PLATFORM_WINDOWS
::CloseHandle(m_FileHandle);
+#else
+ int Fd = int(uintptr_t(m_FileHandle));
+ close(Fd);
+#endif
m_FileHandle = nullptr;
}
}
@@ -86,6 +113,7 @@ BasicFile::Read(void* Data, uint64_t BytesToRead, uint64_t FileOffset)
{
const uint64_t NumberOfBytesToRead = Min(BytesToRead, MaxChunkSize);
+#if ZEN_PLATFORM_WINDOWS
OVERLAPPED Ovl{};
Ovl.Offset = DWORD(FileOffset & 0xffff'ffffu);
@@ -95,6 +123,12 @@ BasicFile::Read(void* Data, uint64_t BytesToRead, uint64_t FileOffset)
BOOL Success = ::ReadFile(m_FileHandle, Data, DWORD(NumberOfBytesToRead), &dwNumberOfBytesRead, &Ovl);
ZEN_ASSERT(dwNumberOfBytesRead == NumberOfBytesToRead);
+#else
+ static_assert(sizeof(off_t) >= sizeof(uint64_t), "sizeof(off_t) does not support large files");
+ int Fd = int(uintptr_t(m_FileHandle));
+ int BytesRead = pread(Fd, Data, NumberOfBytesToRead, FileOffset);
+ bool Success = (BytesRead > 0);
+#endif
if (!Success)
{
@@ -161,6 +195,7 @@ BasicFile::Write(const void* Data, uint64_t Size, uint64_t FileOffset, std::erro
{
const uint64_t NumberOfBytesToWrite = Min(Size, MaxChunkSize);
+#if ZEN_PLATFORM_WINDOWS
OVERLAPPED Ovl{};
Ovl.Offset = DWORD(FileOffset & 0xffff'ffffu);
@@ -169,6 +204,12 @@ BasicFile::Write(const void* Data, uint64_t Size, uint64_t FileOffset, std::erro
DWORD dwNumberOfBytesWritten = 0;
BOOL Success = ::WriteFile(m_FileHandle, Data, DWORD(NumberOfBytesToWrite), &dwNumberOfBytesWritten, &Ovl);
+#else
+ static_assert(sizeof(off_t) >= sizeof(uint64_t), "sizeof(off_t) does not support large files");
+ int Fd = int(uintptr_t(m_FileHandle));
+ int BytesWritten = pwrite(Fd, Data, NumberOfBytesToWrite, FileOffset);
+ bool Success = (BytesWritten > 0);
+#endif
if (!Success)
{
@@ -210,16 +251,29 @@ BasicFile::WriteAll(IoBuffer Data, std::error_code& Ec)
void
BasicFile::Flush()
{
+#if ZEN_PLATFORM_WINDOWS
FlushFileBuffers(m_FileHandle);
+#else
+ int Fd = int(uintptr_t(m_FileHandle));
+ fsync(Fd);
+#endif
}
uint64_t
BasicFile::FileSize()
{
+#if ZEN_PLATFORM_WINDOWS
ULARGE_INTEGER liFileSize;
liFileSize.LowPart = ::GetFileSize(m_FileHandle, &liFileSize.HighPart);
return uint64_t(liFileSize.QuadPart);
+#else
+ int Fd = int(uintptr_t(m_FileHandle));
+ static_assert(sizeof(decltype(stat::st_size)) == sizeof(uint64_t), "fstat() doesn't support large files");
+ struct stat Stat;
+ fstat(Fd, &Stat);
+ return uint64_t(Stat.st_size);
+#endif
}
//////////////////////////////////////////////////////////////////////////
@@ -234,11 +288,16 @@ TemporaryFile::Close()
{
if (m_FileHandle)
{
+#if ZEN_PLATFORM_WINDOWS
// Mark file for deletion when final handle is closed
FILE_DISPOSITION_INFO Fdi{.DeleteFile = TRUE};
SetFileInformationByHandle(m_FileHandle, FileDispositionInfo, &Fdi, sizeof Fdi);
+#else
+ std::filesystem::path FilePath = zen::PathFromHandle(m_FileHandle);
+ unlink(FilePath.c_str());
+#endif
BasicFile::Close();
}
@@ -275,11 +334,18 @@ LockFile::LockFile()
LockFile::~LockFile()
{
+#if ZEN_PLATFORM_LINUX
+ int Fd = int(intptr_t(m_FileHandle));
+ flock(Fd, LOCK_UN | LOCK_NB);
+#elif ZEN_PLATFORM_MAC
+# error check flock() support
+#endif
}
void
LockFile::Create(std::filesystem::path FileName, CbObject Payload, std::error_code& Ec)
{
+#if ZEN_PLATFORM_WINDOWS
Ec.clear();
const DWORD dwCreationDisposition = CREATE_ALWAYS;
@@ -302,6 +368,26 @@ LockFile::Create(std::filesystem::path FileName, CbObject Payload, std::error_co
return;
}
+#elif ZEN_PLATFORM_LINUX
+ int Fd = open(FileName.c_str(), O_RDWR | O_CREAT, 0666);
+ if (Fd < 0)
+ {
+ Ec = zen::MakeErrorCodeFromLastError();
+ return;
+ }
+
+ int LockRet = flock(Fd, LOCK_EX | LOCK_NB);
+ if (LockRet < 0)
+ {
+ Ec = zen::MakeErrorCodeFromLastError();
+ close(Fd);
+ return;
+ }
+
+ void* FileHandle = (void*)uintptr_t(Fd);
+#else
+# error check flock() support
+#endif
m_FileHandle = FileHandle;
diff --git a/zenstore/CAS.cpp b/zenstore/cas.cpp
index d4023bdc4..d4023bdc4 100644
--- a/zenstore/CAS.cpp
+++ b/zenstore/cas.cpp
diff --git a/zenstore/caslog.cpp b/zenstore/caslog.cpp
index 369bc55ad..dc4891e9f 100644
--- a/zenstore/caslog.cpp
+++ b/zenstore/caslog.cpp
@@ -2,7 +2,7 @@
#include <zenstore/cas.h>
-#include "CompactCas.h"
+#include "compactcas.h"
#include <zencore/except.h>
#include <zencore/filesystem.h>
@@ -133,7 +133,7 @@ CasLogFile::Replay(std::function<void(const void*)>&& Handler)
m_File.Read(ReadBuffer.data(), LogDataSize, LogBaseOffset);
- for (int i = 0; i < LogEntryCount; ++i)
+ for (int i = 0; i < int(LogEntryCount); ++i)
{
Handler(ReadBuffer.data() + (i * m_RecordSize));
}
@@ -149,7 +149,7 @@ CasLogFile::Append(const void* DataPointer, uint64_t DataSize)
uint64_t AppendOffset = m_AppendOffset.fetch_add(DataSize);
std::error_code Ec;
- m_File.Write(DataPointer, gsl::narrow<DWORD>(DataSize), AppendOffset, Ec);
+ m_File.Write(DataPointer, gsl::narrow<uint32_t>(DataSize), AppendOffset, Ec);
if (Ec)
{
diff --git a/zenstore/cidstore.cpp b/zenstore/cidstore.cpp
index c5396cff3..8b53a8304 100644
--- a/zenstore/cidstore.cpp
+++ b/zenstore/cidstore.cpp
@@ -7,7 +7,7 @@
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
#include <zencore/string.h>
-#include <zenstore/CAS.h>
+#include <zenstore/cas.h>
#include <zenstore/caslog.h>
#include <filesystem>
diff --git a/zenstore/compactcas.cpp b/zenstore/compactcas.cpp
index d4d29c179..aa60ec37b 100644
--- a/zenstore/compactcas.cpp
+++ b/zenstore/compactcas.cpp
@@ -2,7 +2,7 @@
#include <zenstore/cas.h>
-#include "CompactCas.h"
+#include "compactcas.h"
#include <zencore/compactbinarybuilder.h>
#include <zencore/except.h>
diff --git a/zenstore/compactcas.h b/zenstore/compactcas.h
index f3a933718..974f45a0c 100644
--- a/zenstore/compactcas.h
+++ b/zenstore/compactcas.h
@@ -9,7 +9,6 @@
#include <zencore/string.h>
#include <zencore/thread.h>
#include <zencore/uid.h>
-#include <zencore/windows.h>
#include <zenstore/basicfile.h>
#include <zenstore/cas.h>
#include <zenstore/caslog.h>
@@ -19,6 +18,10 @@ namespace spdlog {
class logger;
}
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+#endif
+
namespace zen {
//////////////////////////////////////////////////////////////////////////
diff --git a/zenstore/filecas.cpp b/zenstore/filecas.cpp
index 2fc968a91..4e4502e6d 100644
--- a/zenstore/filecas.cpp
+++ b/zenstore/filecas.cpp
@@ -1,6 +1,6 @@
// Copyright Epic Games, Inc. All Rights Reserved.
-#include "FileCas.h"
+#include "filecas.h"
#include <zencore/except.h>
#include <zencore/filesystem.h>
@@ -28,7 +28,9 @@
#include <unordered_map>
ZEN_THIRD_PARTY_INCLUDES_START
-#include <atlfile.h>
+#if ZEN_PLATFORM_WINDOWS
+# include <atlfile.h>
+#endif
ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
@@ -38,7 +40,6 @@ using namespace fmt::literals;
FileCasStrategy::ShardingHelper::ShardingHelper(const std::filesystem::path& RootPath, const IoHash& ChunkHash)
{
ShardedPath.Append(RootPath.c_str());
- ShardedPath.Append(std::filesystem::path::preferred_separator);
ExtendableStringBuilder<64> HashString;
ChunkHash.ToHexString(HashString);
@@ -58,13 +59,14 @@ FileCasStrategy::ShardingHelper::ShardingHelper(const std::filesystem::path& Roo
// would probably be a good idea to measure performance for different
// policies and chunk counts
+ ShardedPath.AppendSeparator();
ShardedPath.AppendAsciiRange(str, str + 3);
- ShardedPath.Append(std::filesystem::path::preferred_separator);
+ ShardedPath.AppendSeparator();
ShardedPath.AppendAsciiRange(str + 3, str + 5);
Shard2len = ShardedPath.Size();
- ShardedPath.Append(std::filesystem::path::preferred_separator);
+ ShardedPath.AppendSeparator();
ShardedPath.AppendAsciiRange(str + 5, str + 40);
}
@@ -115,6 +117,9 @@ FileCasStrategy::InsertChunk(IoBuffer Chunk, const IoHash& ChunkHash)
{
ShardingHelper Name(m_Config.RootDirectory.c_str(), ChunkHash);
+ RwLock::ExclusiveLockScope _(LockForHash(ChunkHash));
+
+#if ZEN_PLATFORM_WINDOWS
const HANDLE ChunkFileHandle = FileRef.FileHandle;
auto DeletePayloadFileOnClose = [&] {
@@ -135,8 +140,6 @@ FileCasStrategy::InsertChunk(IoBuffer Chunk, const IoHash& ChunkHash)
//
// Future improvement: maintain Bloom filter to avoid expensive file system probes?
- RwLock::ExclusiveLockScope _(LockForHash(ChunkHash));
-
{
CAtlFile PayloadFile;
@@ -268,6 +271,49 @@ FileCasStrategy::InsertChunk(IoBuffer Chunk, const IoHash& ChunkHash)
ChunkHash);
DeletePayloadFileOnClose();
+#elif ZEN_PLATFORM_LINUX
+ std::filesystem::path SourcePath = PathFromHandle(FileRef.FileHandle);
+ std::filesystem::path DestPath = Name.ShardedPath.c_str();
+ int Ret = link(SourcePath.c_str(), DestPath.c_str());
+ if (Ret < 0 && zen::GetLastError() == ENOENT)
+ {
+ // Destination directory doesn't exist. Create it any try again.
+ CreateDirectories(DestPath.parent_path().c_str());
+ Ret = link(SourcePath.c_str(), DestPath.c_str());
+ }
+ int LinkError = zen::GetLastError();
+
+ // Unlink the file. If the path to unlink didn't exist someone else
+ // beat us to it and that is hunky-dory.
+ if (unlink(SourcePath.c_str()) < 0)
+ {
+ int UnlinkError = zen::GetLastError();
+ if (UnlinkError != ENOENT)
+ {
+ ZEN_WARN("unlink of CAS payload file failed ('{}')", GetSystemErrorAsString(UnlinkError));
+ }
+ }
+
+ // It is possible that someone beat us to it in linking the file. In that
+ // case a "file exists" error is okay. All others are not.
+ if (Ret < 0)
+ {
+ if (LinkError == EEXIST)
+ {
+ return CasStore::InsertResult{.New = false};
+ }
+
+ ZEN_WARN("link of CAS payload file failed ('{}'), falling back to regular write for insert of {}",
+ GetSystemErrorAsString(LinkError),
+ ChunkHash);
+ }
+ else
+ {
+ return CasStore::InsertResult{.New = true};
+ }
+#else
+# error check link/unlink for this platform
+#endif // ZEN_PLATFORM_*
}
return InsertChunk(Chunk.Data(), Chunk.Size(), ChunkHash);
@@ -284,6 +330,7 @@ FileCasStrategy::InsertChunk(const void* const ChunkData, const size_t ChunkSize
//
// Future improvement: maintain Bloom filter to avoid expensive file system probes?
+#if ZEN_PLATFORM_WINDOWS
CAtlFile PayloadFile;
HRESULT hRes = PayloadFile.Create(Name.ShardedPath.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING);
@@ -298,9 +345,18 @@ FileCasStrategy::InsertChunk(const void* const ChunkData, const size_t ChunkSize
}
PayloadFile.Close();
+#elif ZEN_PLATFORM_LINUX
+ if (access(Name.ShardedPath.c_str(), F_OK) == 0)
+ {
+ return CasStore::InsertResult{.New = false};
+ }
+#else
+# error Check access() for this platform
+#endif
RwLock::ExclusiveLockScope _(LockForHash(ChunkHash));
+#if ZEN_PLATFORM_WINDOWS
// For now, use double-checked locking to see if someone else was first
hRes = PayloadFile.Create(Name.ShardedPath.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING);
@@ -336,6 +392,49 @@ FileCasStrategy::InsertChunk(const void* const ChunkData, const size_t ChunkSize
{
ThrowSystemException(hRes, "Failed to open shard file '{}'"_format(WideToUtf8(Name.ShardedPath)));
}
+#else
+ // Attempt to exclusively create the file.
+ auto InternalCreateFile = [&] { return open(Name.ShardedPath.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0666); };
+ int Fd = InternalCreateFile();
+ if (Fd < 0)
+ {
+ switch (zen::GetLastError())
+ {
+ case EEXIST:
+ // Another thread has beat us to it so we're golden.
+ return {.New = false};
+
+ case ENOENT:
+ if (zen::CreateDirectories(std::string_view(Name.ShardedPath.c_str(), Name.Shard2len)))
+ {
+ Fd = InternalCreateFile();
+ if (Fd >= 0)
+ {
+ break;
+ }
+ }
+ ThrowLastError("Failed creating shard directory '{}'"_format(Name.ShardedPath));
+
+ default:
+ ThrowLastError("Unexpected error occurred opening shard file '{}'"_format(Name.ShardedPath));
+ }
+ }
+
+ struct FdWrapper
+ {
+ ~FdWrapper() { Close(); }
+ void Write(const void* Cursor, size_t Size) { (void)!write(Fd, Cursor, Size); }
+ void Close()
+ {
+ if (Fd >= 0)
+ {
+ close(Fd);
+ Fd = -1;
+ }
+ }
+ int Fd;
+ } PayloadFile = {Fd};
+#endif // ZEN_PLATFORM_WINDOWS
size_t ChunkRemain = ChunkSize;
auto ChunkCursor = reinterpret_cast<const uint8_t*>(ChunkData);
@@ -437,13 +536,13 @@ FileCasStrategy::IterateChunks(std::function<void(const IoHash& Hash, BasicFile&
struct Visitor : public FileSystemTraversal::TreeVisitor
{
Visitor(const std::filesystem::path& RootDir) : RootDirectory(RootDir) {}
- virtual void VisitFile(const std::filesystem::path& Parent, const std::wstring_view& File, uint64_t FileSize) override
+ virtual void VisitFile(const std::filesystem::path& Parent, const path_view& File, uint64_t FileSize) override
{
ZEN_UNUSED(FileSize);
std::filesystem::path RelPath = std::filesystem::relative(Parent, RootDirectory);
- std::wstring PathString = RelPath.native();
+ std::filesystem::path::string_type PathString = RelPath.native();
if ((PathString.size() == (3 + 2 + 1)) && (File.size() == (40 - 3 - 2)))
{
@@ -453,12 +552,15 @@ FileCasStrategy::IterateChunks(std::function<void(const IoHash& Hash, BasicFile&
}
PathString.append(File);
- StringBuilder<64> Utf8;
- WideToUtf8(PathString, Utf8);
-
// TODO: should validate that we're actually dealing with a valid hex string here
+#if ZEN_PLATFORM_WINDOWS
+ StringBuilder<64> Utf8;
+ WideToUtf8(PathString, Utf8);
IoHash NameHash = IoHash::FromHexString({Utf8.Data(), Utf8.Size()});
+#else
+ IoHash NameHash = IoHash::FromHexString(PathString);
+#endif
BasicFile PayloadFile;
std::error_code Ec;
@@ -471,8 +573,7 @@ FileCasStrategy::IterateChunks(std::function<void(const IoHash& Hash, BasicFile&
}
}
- virtual bool VisitDirectory([[maybe_unused]] const std::filesystem::path& Parent,
- [[maybe_unused]] const std::wstring_view& DirectoryName)
+ virtual bool VisitDirectory([[maybe_unused]] const std::filesystem::path& Parent, [[maybe_unused]] const path_view& DirectoryName)
{
return true;
}
diff --git a/zenstore/filecas.h b/zenstore/filecas.h
index a229ba6f1..ef67ae9eb 100644
--- a/zenstore/filecas.h
+++ b/zenstore/filecas.h
@@ -4,9 +4,9 @@
#include <zencore/zencore.h>
+#include <zencore/filesystem.h>
#include <zencore/iobuffer.h>
#include <zencore/iohash.h>
-#include <zencore/string.h>
#include <zencore/thread.h>
#include <zenstore/cas.h>
#include <zenstore/caslog.h>
@@ -74,8 +74,8 @@ private:
{
ShardingHelper(const std::filesystem::path& RootPath, const IoHash& ChunkHash);
- size_t Shard2len = 0;
- ExtendableWideStringBuilder<128> ShardedPath;
+ size_t Shard2len = 0;
+ ExtendablePathBuilder<128> ShardedPath;
};
};
diff --git a/zenstore/gc.cpp b/zenstore/gc.cpp
index 307adc04e..7c6fa4dab 100644
--- a/zenstore/gc.cpp
+++ b/zenstore/gc.cpp
@@ -306,7 +306,7 @@ CasGc::CollectGarbage(GcContext& GcCtx)
}
// Remove Cid to CAS hash mappings. Scrub?
-
+
if (CidStore* CidStore = m_CidStore)
{
CidStore->RemoveCids(GcCtx.DeletedCas());
diff --git a/zenstore/include/zenstore/basicfile.h b/zenstore/include/zenstore/basicfile.h
index e4414787c..2df016c76 100644
--- a/zenstore/include/zenstore/basicfile.h
+++ b/zenstore/include/zenstore/basicfile.h
@@ -5,7 +5,6 @@
#include "zenstore.h"
#include <zencore/iobuffer.h>
-#include <zencore/windows.h>
#include <filesystem>
#include <functional>
diff --git a/zenstore/include/zenstore/CAS.h b/zenstore/include/zenstore/cas.h
index 2e530c418..9371e4de0 100644
--- a/zenstore/include/zenstore/CAS.h
+++ b/zenstore/include/zenstore/cas.h
@@ -45,9 +45,9 @@ public:
void AddChunksToSet(std::span<const IoHash> HashesToAdd);
void RemoveChunksIf(std::function<bool(const IoHash& CandidateHash)>&& Predicate);
void IterateChunks(std::function<void(const IoHash& ChunkHash)>&& Callback);
- inline [[nodiscard]] bool ContainsChunk(const IoHash& Hash) const { return m_ChunkSet.find(Hash) != m_ChunkSet.end(); }
- inline [[nodiscard]] bool IsEmpty() const { return m_ChunkSet.empty(); }
- inline [[nodiscard]] size_t GetSize() const { return m_ChunkSet.size(); }
+ [[nodiscard]] inline bool ContainsChunk(const IoHash& Hash) const { return m_ChunkSet.find(Hash) != m_ChunkSet.end(); }
+ [[nodiscard]] inline bool IsEmpty() const { return m_ChunkSet.empty(); }
+ [[nodiscard]] inline size_t GetSize() const { return m_ChunkSet.size(); }
inline void FilterChunks(std::span<const IoHash> Candidates, std::invocable<const IoHash&> auto MatchFunc)
{
diff --git a/zenstore/include/zenstore/caslog.h b/zenstore/include/zenstore/caslog.h
index 9b2ef574c..1ecb721f7 100644
--- a/zenstore/include/zenstore/caslog.h
+++ b/zenstore/include/zenstore/caslog.h
@@ -8,10 +8,13 @@
#include <zencore/string.h>
#include <zencore/thread.h>
#include <zencore/uid.h>
-#include <zencore/windows.h>
#include <zenstore/basicfile.h>
#include <zenstore/cas.h>
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+#endif
+
#include <functional>
namespace zen {
diff --git a/zenstore/include/zenstore/cidstore.h b/zenstore/include/zenstore/cidstore.h
index a8cb87f40..04a3d419c 100644
--- a/zenstore/include/zenstore/cidstore.h
+++ b/zenstore/include/zenstore/cidstore.h
@@ -5,7 +5,7 @@
#include "zenstore.h"
#include <zencore/iohash.h>
-#include <zenstore/CAS.h>
+#include <zenstore/cas.h>
ZEN_THIRD_PARTY_INCLUDES_START
#include <tsl/robin_map.h>
diff --git a/zenstore/zenstore.cpp b/zenstore/zenstore.cpp
index 337a1c75b..dbb3dbbf7 100644
--- a/zenstore/zenstore.cpp
+++ b/zenstore/zenstore.cpp
@@ -2,8 +2,8 @@
#include "zenstore/zenstore.h"
-#include <zenstore/CAS.h>
#include <zenstore/basicfile.h>
+#include <zenstore/cas.h>
#include <zenstore/gc.h>
#include "compactcas.h"
#include "filecas.h"
diff --git a/zenstore/zenstore.vcxproj b/zenstore/zenstore.vcxproj
index 832ea8159..77a4dff7d 100644
--- a/zenstore/zenstore.vcxproj
+++ b/zenstore/zenstore.vcxproj
@@ -28,7 +28,7 @@
<ClInclude Include="include\zenstore\cidstore.h" />
<ClInclude Include="include\zenstore\gc.h" />
<ClInclude Include="include\zenstore\scrub.h" />
- <ClInclude Include="include\zenstore\CAS.h" />
+ <ClInclude Include="include\zenstore\cas.h" />
<ClInclude Include="include\zenstore\caslog.h" />
<ClInclude Include="include\zenstore\zenstore.h" />
</ItemGroup>
diff --git a/zenstore/zenstore.vcxproj.filters b/zenstore/zenstore.vcxproj.filters
index 8a52c69f6..904de0748 100644
--- a/zenstore/zenstore.vcxproj.filters
+++ b/zenstore/zenstore.vcxproj.filters
@@ -14,7 +14,7 @@
<ItemGroup>
<ClInclude Include="compactcas.h" />
<ClInclude Include="filecas.h" />
- <ClInclude Include="include\zenstore\CAS.h" />
+ <ClInclude Include="include\zenstore\cas.h" />
<ClInclude Include="include\zenstore\caslog.h" />
<ClInclude Include="include\zenstore\gc.h" />
<ClInclude Include="include\zenstore\scrub.h" />