From da0ca23fa55f7e900853bdfd06523b78fce32259 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Sat, 28 May 2022 00:29:17 +0200 Subject: Enable FILE_SHARE_DELETE on standalone files in disk buckets This allows us to delete the file even if it is open for read. We do a delete, the rename since we are not allowed to do a rename-overwrite, only delete. As we have the shard lock for the file we want to replace we can safely do a delete+rename. In the rare case that we fail to rename the file into place the old data is lost. As this is a *cache* and it should be very rare this is OK. --- zencore/iobuffer.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'zencore/iobuffer.cpp') diff --git a/zencore/iobuffer.cpp b/zencore/iobuffer.cpp index c4b7f7bdf..61db25d0f 100644 --- a/zencore/iobuffer.cpp +++ b/zencore/iobuffer.cpp @@ -469,6 +469,51 @@ IoBufferBuilder::MakeFromFileHandle(void* FileHandle, uint64_t Offset, uint64_t return IoBuffer(IoBuffer::BorrowedFile, FileHandle, Offset, Size); } +IoBuffer +IoBufferBuilder::MakeFromFileWithSharedDelete(const std::filesystem::path& FileName) +{ + uint64_t Size; + +#if ZEN_PLATFORM_WINDOWS + CAtlFile DataFile; + + HRESULT hRes = DataFile.Create(FileName.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, OPEN_EXISTING); + + if (FAILED(hRes)) + { + return {}; + } + + DataFile.GetSize((ULONGLONG&)Size); +#else + int Fd = open(FileName.c_str(), O_RDONLY | O_CLOEXEC); + if (Fd < 0) + { + return {}; + } + + static_assert(sizeof(decltype(stat::st_size)) == sizeof(uint64_t), "fstat() doesn't support large files"); + struct stat Stat; + fstat(Fd, &Stat); + Size = Stat.st_size; +#endif // ZEN_PLATFORM_WINDOWS + + if (Size) + { +#if ZEN_PLATFORM_WINDOWS + void* Fd = DataFile.Detach(); +#endif + return IoBuffer(IoBuffer::File, (void*)uintptr_t(Fd), 0, Size); + } + +#if !ZEN_PLATFORM_WINDOWS + close(Fd); +#endif + + // For an empty file, we may as well just return an empty memory IoBuffer + return IoBuffer(IoBuffer::Wrap, "", 0); +} + IoBuffer IoBufferBuilder::MakeFromFile(const std::filesystem::path& FileName, uint64_t Offset, uint64_t Size) { -- cgit v1.2.3