Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2019-09-25 18:31:49 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2019-09-25 18:31:49 +0300
commitaea9a0bda5ffc7aac4ba5e8c6582893b7aad7d90 (patch)
treed5209ec744135e580d7702636064dfe37b7cd9f0
parenta3942420524c91179009e06b9d77cfb4326dcf7f (diff)
LLFIO is now make installable and cmake find_package()-able, which should implement cmake hunter support.
Significantly slimmed down the headers being dragged in by the default LLFIO include, specifically that outcome<T> is no longer dragged in, and: - #36 Async file i/o and storage profile have been modularised out of the default headers. - #36 Mapped file i/o can be modularised out of the default headers. Changed barrier kind to class enum, as per latest WG21 spec.
-rw-r--r--CMakeLists.txt11
m---------doc/html17
-rw-r--r--example/ts_examples.cpp1
-rw-r--r--include/kvstore/kvstore.hpp12
-rw-r--r--include/llfio/revision.hpp6
-rw-r--r--include/llfio/v2.0/algorithm/shared_fs_mutex/base.hpp12
-rw-r--r--include/llfio/v2.0/algorithm/shared_fs_mutex/byte_ranges.hpp12
-rw-r--r--include/llfio/v2.0/algorithm/shared_fs_mutex/lock_files.hpp12
-rw-r--r--include/llfio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp22
-rw-r--r--include/llfio/v2.0/async_file_handle.hpp44
-rw-r--r--include/llfio/v2.0/config.hpp28
-rw-r--r--include/llfio/v2.0/detail/impl/posix/async_file_handle.ipp4
-rw-r--r--include/llfio/v2.0/detail/impl/posix/directory_handle.ipp10
-rw-r--r--include/llfio/v2.0/detail/impl/posix/file_handle.ipp13
-rw-r--r--include/llfio/v2.0/detail/impl/posix/map_handle.ipp22
-rw-r--r--include/llfio/v2.0/detail/impl/posix/utils.ipp12
-rw-r--r--include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp17
-rw-r--r--include/llfio/v2.0/detail/impl/storage_profile.ipp12
-rw-r--r--include/llfio/v2.0/detail/impl/windows/async_file_handle.ipp4
-rw-r--r--include/llfio/v2.0/detail/impl/windows/file_handle.ipp8
-rw-r--r--include/llfio/v2.0/detail/impl/windows/map_handle.ipp25
-rw-r--r--include/llfio/v2.0/detail/impl/windows/utils.ipp2
-rw-r--r--include/llfio/v2.0/fast_random_file_handle.hpp4
-rw-r--r--include/llfio/v2.0/file_handle.hpp9
-rw-r--r--include/llfio/v2.0/fs_handle.hpp64
-rw-r--r--include/llfio/v2.0/handle.hpp4
-rw-r--r--include/llfio/v2.0/io_handle.hpp149
-rw-r--r--include/llfio/v2.0/llfio.hpp13
-rw-r--r--include/llfio/v2.0/map_handle.hpp6
-rw-r--r--include/llfio/v2.0/mapped_file_handle.hpp2
m---------include/llfio/v2.0/outcome0
-rw-r--r--include/llfio/v2.0/path_discovery.hpp2
m---------include/llfio/v2.0/quickcpplib0
-rw-r--r--include/llfio/v2.0/status_code.hpp9
-rw-r--r--include/llfio/v2.0/storage_profile.hpp7
-rw-r--r--include/llfio/v2.0/utils.hpp2
-rw-r--r--programs/CMakeLists.txt2
-rw-r--r--programs/benchmark-iostreams/main.cpp8
-rw-r--r--programs/benchmark-locking/main.cpp2
-rw-r--r--programs/fs-probe/main.cpp2
-rw-r--r--programs/key-value-store/include/key_value_store.hpp6
-rw-r--r--programs/key-value-store/main.cpp2
m---------test/kerneltest0
-rw-r--r--test/test_kernel_decl.hpp4
-rw-r--r--test/tests/fast_random_file_handle.cpp10
-rw-r--r--test/tests/handle_adapter_xor.cpp11
46 files changed, 253 insertions, 371 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e04a3638..c1420f33 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -138,7 +138,7 @@ if(MSVC)
endif()
endif()
if(CLANG OR GCC)
- CheckCXXHasCoroutines(_CLANG_GCC "-std=c++14 -fcoroutines-ts")
+ CheckCXXHasCoroutines(_CLANG_GCC "-fcoroutines-ts")
if(CXX_HAS_COROUTINES_CLANG_GCC)
all_compile_options(PUBLIC "-fcoroutines-ts")
all_compile_definitions(PUBLIC "LLFIO_HAVE_COROUTINES=1")
@@ -176,6 +176,10 @@ if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
all_link_libraries(PUBLIC ${libcxx_cxxexperimental})
endif()
# Set any macros this library requires
+all_compile_definitions(PRIVATE LLFIO_INCLUDE_ASYNC_FILE_HANDLE=1 LLFIO_INCLUDE_STORAGE_PROFILE=1)
+foreach(target ${llfio_EXAMPLE_TARGETS})
+ target_compile_definitions(${target} PRIVATE LLFIO_INCLUDE_ASYNC_FILE_HANDLE=1 LLFIO_INCLUDE_STORAGE_PROFILE=1)
+endforeach()
if(LLFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE)
all_compile_definitions(PUBLIC LLFIO_EXPERIMENTAL_STATUS_CODE=1)
endif()
@@ -208,7 +212,10 @@ endif()
# For all possible configurations of this library, add each test
include(QuickCppLibMakeStandardTests)
-# For each test target, link to kerneltest
+# For each test target, set definitions and linkage
+foreach(target ${llfio_COMPILE_TEST_TARGETS} ${llfio_TEST_TARGETS})
+ target_compile_definitions(${target} PRIVATE LLFIO_INCLUDE_ASYNC_FILE_HANDLE=1 LLFIO_INCLUDE_STORAGE_PROFILE=1)
+endforeach()
foreach(test_target ${llfio_TEST_TARGETS})
target_link_libraries(${test_target} PRIVATE kerneltest::hl)
endforeach()
diff --git a/doc/html b/doc/html
-Subproject b5c88a3fa6f2f11f5f10ad668b7b6b04dd819a4
+Subproject 11e1d127ed5ff762f836238235cd3c57fc434b6
diff --git a/example/ts_examples.cpp b/example/ts_examples.cpp
index b93caf18..b0f81cf5 100644
--- a/example/ts_examples.cpp
+++ b/example/ts_examples.cpp
@@ -72,6 +72,7 @@ inline io_handle::buffers_type read_all(io_handle &h, io_handle::io_request<io_h
}
// Partial fill buffers with current request
io_handle::buffers_type filled = h.read(creq, nd) VALUE;
+ (void) filled;
// Adjust output buffers by what was filled, and prepare input
// buffers for next round of partial fill
diff --git a/include/kvstore/kvstore.hpp b/include/kvstore/kvstore.hpp
index d21eff8e..9d3e30ab 100644
--- a/include/kvstore/kvstore.hpp
+++ b/include/kvstore/kvstore.hpp
@@ -27,17 +27,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../llfio/v2.0/file_handle.hpp"
-#ifdef __has_include
-#if __has_include("../llfio/v2.0/quickcpplib/include/memory_resource.hpp")
-#include "../llfio/v2.0/quickcpplib/include/memory_resource.hpp"
-#else
-#include "quickcpplib/include/memory_resource.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/memory_resource.hpp"
-#else
-#include "../llfio/v2.0/quickcpplib/include/memory_resource.hpp"
-#endif
+#include "quickcpplib/memory_resource.hpp"
//! \file kvstore.hpp Provides the abstract interface for a key-value store.
diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp
index 70b6096c..399796fa 100644
--- a/include/llfio/revision.hpp
+++ b/include/llfio/revision.hpp
@@ -1,4 +1,4 @@
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
-#define LLFIO_PREVIOUS_COMMIT_REF 5129a908d2855e7f22f5e1f3577a91826115075d
-#define LLFIO_PREVIOUS_COMMIT_DATE "2019-09-18 22:06:21 +00:00"
-#define LLFIO_PREVIOUS_COMMIT_UNIQUE 5129a908
+#define LLFIO_PREVIOUS_COMMIT_REF a3942420524c91179009e06b9d77cfb4326dcf7f
+#define LLFIO_PREVIOUS_COMMIT_DATE "2019-09-19 09:51:59 +00:00"
+#define LLFIO_PREVIOUS_COMMIT_UNIQUE a3942420
diff --git a/include/llfio/v2.0/algorithm/shared_fs_mutex/base.hpp b/include/llfio/v2.0/algorithm/shared_fs_mutex/base.hpp
index c3e881b8..8e339d13 100644
--- a/include/llfio/v2.0/algorithm/shared_fs_mutex/base.hpp
+++ b/include/llfio/v2.0/algorithm/shared_fs_mutex/base.hpp
@@ -27,17 +27,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../handle.hpp"
-#ifdef __has_include
-#if __has_include("../../quickcpplib/include/algorithm/hash.hpp")
-#include "../../quickcpplib/include/algorithm/hash.hpp"
-#else
-#include "quickcpplib/include/algorithm/hash.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/algorithm/hash.hpp"
-#else
-#include "../../quickcpplib/include/algorithm/hash.hpp"
-#endif
+#include "quickcpplib/algorithm/hash.hpp"
//! \file base.hpp Provides algorithm::shared_fs_mutex::shared_fs_mutex
diff --git a/include/llfio/v2.0/algorithm/shared_fs_mutex/byte_ranges.hpp b/include/llfio/v2.0/algorithm/shared_fs_mutex/byte_ranges.hpp
index dfc99e9c..cb42ce05 100644
--- a/include/llfio/v2.0/algorithm/shared_fs_mutex/byte_ranges.hpp
+++ b/include/llfio/v2.0/algorithm/shared_fs_mutex/byte_ranges.hpp
@@ -28,17 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../file_handle.hpp"
#include "base.hpp"
-#ifdef __has_include
-#if __has_include("../../quickcpplib/include/algorithm/small_prng.hpp")
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#endif
+#include "quickcpplib/algorithm/small_prng.hpp"
//! \file byte_ranges.hpp Provides algorithm::shared_fs_mutex::byte_ranges
diff --git a/include/llfio/v2.0/algorithm/shared_fs_mutex/lock_files.hpp b/include/llfio/v2.0/algorithm/shared_fs_mutex/lock_files.hpp
index 6534767b..62042cd2 100644
--- a/include/llfio/v2.0/algorithm/shared_fs_mutex/lock_files.hpp
+++ b/include/llfio/v2.0/algorithm/shared_fs_mutex/lock_files.hpp
@@ -28,17 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../file_handle.hpp"
#include "base.hpp"
-#ifdef __has_include
-#if __has_include("../../quickcpplib/include/algorithm/small_prng.hpp")
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#endif
+#include "quickcpplib/algorithm/small_prng.hpp"
//! \file lock_files.hpp Provides algorithm::shared_fs_mutex::lock_files
diff --git a/include/llfio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp b/include/llfio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp
index 7f8ff236..9b8c6941 100644
--- a/include/llfio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp
+++ b/include/llfio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp
@@ -28,25 +28,9 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../map_handle.hpp"
#include "base.hpp"
-#ifdef __has_include
-#if __has_include("../../quickcpplib/include/algorithm/hash.hpp")
-#include "../../quickcpplib/include/algorithm/hash.hpp"
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#include "../../quickcpplib/include/spinlock.hpp"
-#else
-#include "quickcpplib/include/algorithm/hash.hpp"
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#include "quickcpplib/include/spinlock.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/algorithm/hash.hpp"
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#include "quickcpplib/include/spinlock.hpp"
-#else
-#include "../../quickcpplib/include/algorithm/hash.hpp"
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#include "../../quickcpplib/include/spinlock.hpp"
-#endif
+#include "quickcpplib/algorithm/hash.hpp"
+#include "quickcpplib/algorithm/small_prng.hpp"
+#include "quickcpplib/spinlock.hpp"
//! \file memory_map.hpp Provides algorithm::shared_fs_mutex::memory_map
diff --git a/include/llfio/v2.0/async_file_handle.hpp b/include/llfio/v2.0/async_file_handle.hpp
index eea3288d..b7133c61 100644
--- a/include/llfio/v2.0/async_file_handle.hpp
+++ b/include/llfio/v2.0/async_file_handle.hpp
@@ -213,7 +213,7 @@ public:
}
LLFIO_MAKE_FREE_FUNCTION
- LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept override;
+ LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), barrier_kind kind = barrier_kind::nowait_data_only, deadline d = deadline()) noexcept override;
/*! Clone this handle to a different io_service (copy constructor is disabled to avoid accidental copying)
\errors Any of the values POSIX dup() or DuplicateHandle() can return.
@@ -367,10 +367,7 @@ public:
which always write barrier the entire file. Supplying a default initialised reqs write barriers the entire file.
\param completion A callable to call upon i/o completion. Spec is `void(async_file_handle *, io_result<const_buffers_type> &)`.
Note that buffers returned may not be buffers input, see documentation for `barrier()`.
- \param wait_for_device True if you want the call to wait until data reaches storage and that storage
- has acknowledged the data is physically written. Slow.
- \param and_metadata True if you want the call to sync the metadata for retrieving the writes before the
- barrier after a sudden power loss event. Slow.
+ \param kind Which kind of write reordering barrier to perform.
\param mem Optional span of memory to use to avoid using `calloc()`. Note span MUST be all bits zero on entry.
\errors As for `barrier()`, plus `ENOMEM`.
\mallocs If mem is not set, one calloc, one free. The allocation is unavoidable due to the need to store a type
@@ -379,7 +376,7 @@ public:
LLFIO_MAKE_FREE_FUNCTION
template <class CompletionRoutine> //
LLFIO_REQUIRES(detail::is_invocable_r<void, CompletionRoutine, async_file_handle *, io_result<const_buffers_type> &>::value) //
- result<io_state_ptr> async_barrier(io_request<const_buffers_type> reqs, CompletionRoutine &&completion, bool wait_for_device = false, bool and_metadata = false, span<char> mem = {}) noexcept
+ result<io_state_ptr> async_barrier(io_request<const_buffers_type> reqs, CompletionRoutine &&completion, barrier_kind kind = barrier_kind::nowait_data_only, span<char> mem = {}) noexcept
{
LLFIO_LOG_FUNCTION_CALL(this);
struct completion_handler : _erased_completion_handler
@@ -401,15 +398,15 @@ public:
void *address() noexcept final { return &completion; }
} ch{std::forward<CompletionRoutine>(completion)};
operation_t operation = operation_t::fsync_sync;
- if(!wait_for_device && and_metadata)
+ if(kind == barrier_kind::nowait_all)
{
operation = operation_t::fsync_async;
}
- else if(wait_for_device && !and_metadata)
+ else if(kind == barrier_kind::wait_data_only)
{
operation = operation_t::dsync_sync;
}
- else if(!wait_for_device && !and_metadata)
+ else if(kind == barrier_kind::nowait_data_only)
{
operation = operation_t::dsync_async;
}
@@ -689,35 +686,6 @@ inline result<async_file_handle> async_temp_inode(io_service &service, const pat
{
return async_file_handle::async_temp_inode(std::forward<decltype(service)>(service), std::forward<decltype(dir)>(dir), std::forward<decltype(_mode)>(_mode), std::forward<decltype(flags)>(flags));
}
-inline async_file_handle::io_result<async_file_handle::const_buffers_type> barrier(async_file_handle &self, async_file_handle::io_request<async_file_handle::const_buffers_type> reqs = async_file_handle::io_request<async_file_handle::const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false,
- deadline d = deadline()) noexcept
-{
- return self.barrier(std::forward<decltype(reqs)>(reqs), std::forward<decltype(wait_for_device)>(wait_for_device), std::forward<decltype(and_metadata)>(and_metadata), std::forward<decltype(d)>(d));
-}
-/*! \brief Schedule a barrier to occur asynchronously.
-
-\note All the caveats and exclusions which apply to `barrier()` also apply here. Note that Microsoft Windows
-does not support asynchronously executed barriers, and this call will fail on that operating system.
-
-\return Either an io_state_ptr to the i/o in progress, or an error code.
-\param self The object whose member function to call.
-\param reqs A scatter-gather and offset request for what range to barrier. May be ignored on some platforms
-which always write barrier the entire file. Supplying a default initialised reqs write barriers the entire file.
-\param completion A callable to call upon i/o completion. Spec is `void(async_file_handle *, io_result<const_buffers_type> &)`.
-Note that buffers returned may not be buffers input, see documentation for `barrier()`.
-\param wait_for_device True if you want the call to wait until data reaches storage and that storage
-has acknowledged the data is physically written. Slow.
-\param and_metadata True if you want the call to sync the metadata for retrieving the writes before the
-barrier after a sudden power loss event. Slow.
-\param mem Optional span of memory to use to avoid using `calloc()`. Note span MUST be all bits zero on entry.
-\errors As for `barrier()`, plus `ENOMEM`.
-\mallocs If mem is not set, one calloc, one free. The allocation is unavoidable due to the need to store a type
-erased completion handler of unknown type and state per buffers input.
-*/
-template <class CompletionRoutine> inline result<async_file_handle::io_state_ptr> async_barrier(async_file_handle &self, async_file_handle::io_request<async_file_handle::const_buffers_type> reqs, CompletionRoutine &&completion, bool wait_for_device = false, bool and_metadata = false, span<char> mem = {}) noexcept
-{
- return self.async_barrier(std::forward<decltype(reqs)>(reqs), std::forward<decltype(completion)>(completion), std::forward<decltype(wait_for_device)>(wait_for_device), std::forward<decltype(and_metadata)>(and_metadata), std::forward<decltype(mem)>(mem));
-}
/*! \brief Schedule a read to occur asynchronously.
Note that some OS kernels can only process a limited number async i/o
diff --git a/include/llfio/v2.0/config.hpp b/include/llfio/v2.0/config.hpp
index 692127e0..52766103 100644
--- a/include/llfio/v2.0/config.hpp
+++ b/include/llfio/v2.0/config.hpp
@@ -109,7 +109,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <_mingw.h>
#endif
-#include "quickcpplib/include/cpp_feature.h"
+#include "quickcpplib/cpp_feature.h"
#ifndef __cpp_exceptions
#error LLFIO needs C++ exceptions to be turned on
@@ -144,7 +144,7 @@ Distributed under the Boost Software License, Version 1.0.
#endif
-#include "quickcpplib/include/import.h"
+#include "quickcpplib/import.h"
#if defined(LLFIO_UNSTABLE_VERSION) && !defined(LLFIO_DISABLE_ABI_PERMUTATION)
#include "../revision.hpp"
@@ -214,10 +214,10 @@ class file_handle;
LLFIO_V2_NAMESPACE_END
// Bring in the Boost-lite macros
-#include "quickcpplib/include/config.hpp"
+#include "quickcpplib/config.hpp"
#if LLFIO_LOGGING_LEVEL
-#include "quickcpplib/include/ringbuffer_log.hpp"
-#include "quickcpplib/include/utils/thread.hpp"
+#include "quickcpplib/ringbuffer_log.hpp"
+#include "quickcpplib/utils/thread.hpp"
#endif
// Bring in filesystem
#if defined(__has_include)
@@ -307,45 +307,45 @@ LLFIO_V2_NAMESPACE_END
#endif
// Bring in bitfields
-#include "quickcpplib/include/bitfield.hpp"
+#include "quickcpplib/bitfield.hpp"
// Bring in scoped undo
-#include "quickcpplib/include/scoped_undo.hpp"
+#include "quickcpplib/scoped_undo.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using QUICKCPPLIB_NAMESPACE::scoped_undo::undoer;
LLFIO_V2_NAMESPACE_END
// Bring in a span implementation
-#include "quickcpplib/include/span.hpp"
+#include "quickcpplib/span.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::span;
LLFIO_V2_NAMESPACE_END
// Bring in an optional implementation
-#include "quickcpplib/include/optional.hpp"
+#include "quickcpplib/optional.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::optional;
LLFIO_V2_NAMESPACE_END
// Bring in a byte implementation
-#include "quickcpplib/include/byte.hpp"
+#include "quickcpplib/byte.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using QUICKCPPLIB_NAMESPACE::byte::byte;
using QUICKCPPLIB_NAMESPACE::byte::to_byte;
LLFIO_V2_NAMESPACE_END
// Bring in a string_view implementation
-#include "quickcpplib/include/string_view.hpp"
+#include "quickcpplib/string_view.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::string_view;
LLFIO_V2_NAMESPACE_END
// Bring in an ensure_flushes implementation
-#include "quickcpplib/include/mem_flush_loads_stores.hpp"
+#include "quickcpplib/mem_flush_loads_stores.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::mem_flush_loads_stores;
LLFIO_V2_NAMESPACE_END
// Bring in a detach_cast implementation
-#include "quickcpplib/include/detach_cast.hpp"
+#include "quickcpplib/detach_cast.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::detach_cast;
LLFIO_V2_NAMESPACE_END
// Bring in an in_place_detach implementation
-#include "quickcpplib/include/in_place_detach_attach.hpp"
+#include "quickcpplib/in_place_detach_attach.hpp"
LLFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::in_place_attach_detach;
using QUICKCPPLIB_NAMESPACE::in_place_attach_detach::in_place_attach;
diff --git a/include/llfio/v2.0/detail/impl/posix/async_file_handle.ipp b/include/llfio/v2.0/detail/impl/posix/async_file_handle.ipp
index 58b55479..7d03cf2f 100644
--- a/include/llfio/v2.0/detail/impl/posix/async_file_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/posix/async_file_handle.ipp
@@ -32,11 +32,11 @@ Distributed under the Boost Software License, Version 1.0.
LLFIO_V2_NAMESPACE_BEGIN
-async_file_handle::io_result<async_file_handle::const_buffers_type> async_file_handle::barrier(async_file_handle::io_request<async_file_handle::const_buffers_type> reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept
+async_file_handle::io_result<async_file_handle::const_buffers_type> async_file_handle::barrier(async_file_handle::io_request<async_file_handle::const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept
{
LLFIO_LOG_FUNCTION_CALL(this);
optional<io_result<const_buffers_type>> ret;
- OUTCOME_TRY(io_state, async_barrier(reqs, [&ret](async_file_handle *, io_result<const_buffers_type> &&result) { ret = std::move(result); }, wait_for_device, and_metadata));
+ OUTCOME_TRY(io_state, async_barrier(reqs, [&ret](async_file_handle *, io_result<const_buffers_type> &&result) { ret = std::move(result); }, kind));
(void) io_state;
// While i/o is not done pump i/o completion
diff --git a/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp b/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp
index 30278c38..dfa79a29 100644
--- a/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp
@@ -26,15 +26,7 @@ http://www.boost.org/LICENSE_1_0.txt)
#include "import.hpp"
#ifdef QUICKCPPLIB_ENABLE_VALGRIND
-#ifdef __has_include
-#if __has_include("../../../quickcpplib/valgrind/memcheck.h")
-#include "../../../quickcpplib/valgrind/memcheck.h"
-#else
-#include "quickcpplib/valgrind/memcheck.h"
-#endif
-#else
-#include "quickcpplib/valgrind/memcheck.h"
-#endif
+#include "../valgrind/memcheck.h" // from quickcpplib include directory
#define LLFIO_VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(a, b) VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE((a), (b))
#else
#define LLFIO_VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(a, b)
diff --git a/include/llfio/v2.0/detail/impl/posix/file_handle.ipp b/include/llfio/v2.0/detail/impl/posix/file_handle.ipp
index b96232f0..4f7cd04c 100644
--- a/include/llfio/v2.0/detail/impl/posix/file_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/posix/file_handle.ipp
@@ -154,17 +154,16 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode,
}
}
-file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(file_handle::io_request<file_handle::const_buffers_type> reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept
+file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(file_handle::io_request<file_handle::const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept
{
- (void) wait_for_device;
- (void) and_metadata;
+ (void) kind;
LLFIO_LOG_FUNCTION_CALL(this);
if(d)
{
return errc::not_supported;
}
#ifdef __linux__
- if(!and_metadata)
+ if(kind == barrier_kind::nowait_data_only || kind == barrier_kind::wait_data_only)
{
// Linux has a lovely dedicated syscall giving us exactly what we need here
extent_type offset = reqs.offset, bytes = 0;
@@ -174,7 +173,7 @@ file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(fil
bytes += req.size();
}
unsigned flags = SYNC_FILE_RANGE_WRITE; // start writing all dirty pages in range now
- if(wait_for_device)
+ if(kind == barrier_kind::wait_data_only)
{
flags |= SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WAIT_AFTER; // block until they're on storage
}
@@ -185,7 +184,7 @@ file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(fil
}
#endif
#if !defined(__FreeBSD__) && !defined(__APPLE__) // neither of these have fdatasync()
- if(!and_metadata)
+ if(kind == barrier_kind::nowait_data_only || kind == barrier_kind::wait_data_only)
{
if(-1 == ::fdatasync(_v.fd))
{
@@ -195,7 +194,7 @@ file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(fil
}
#endif
#ifdef __APPLE__
- if(!wait_for_device)
+ if(kind == barrier_kind::nowait_data_only || kind == barrier_kind::nowait_all)
{
// OS X fsync doesn't wait for the device to flush its buffers
if(-1 == ::fsync(_v.fd))
diff --git a/include/llfio/v2.0/detail/impl/posix/map_handle.ipp b/include/llfio/v2.0/detail/impl/posix/map_handle.ipp
index ccb26b2c..bf843c64 100644
--- a/include/llfio/v2.0/detail/impl/posix/map_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/posix/map_handle.ipp
@@ -25,15 +25,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../../map_handle.hpp"
#include "../../../utils.hpp"
-#ifdef __has_include
-#if __has_include("../../../quickcpplib/include/signal_guard.hpp")
-#include "../../../quickcpplib/include/signal_guard.hpp"
-#else
-#include "quickcpplib/include/signal_guard.hpp"
-#endif
-#else
-#include "quickcpplib/include/signal_guard.hpp"
-#endif
+#include "quickcpplib/signal_guard.hpp"
#include <sys/mman.h>
@@ -156,7 +148,7 @@ result<void> map_handle::close() noexcept
{
if(is_writable() && (_flag & section_handle::flag::barrier_on_close))
{
- OUTCOME_TRYV(map_handle::barrier({}, true, false));
+ OUTCOME_TRYV(map_handle::barrier({}, barrier_kind::wait_all));
}
// printf("%d munmap %p-%p\n", getpid(), _addr, _addr+_reservation);
if(-1 == ::munmap(_addr, _reservation))
@@ -181,7 +173,7 @@ native_handle_type map_handle::release() noexcept
return {};
}
-map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_handle::io_request<map_handle::const_buffers_type> reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept
+map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_handle::io_request<map_handle::const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept
{
LLFIO_LOG_FUNCTION_CALL(this);
byte *addr = _addr + reqs.offset;
@@ -201,7 +193,7 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
bytes = _length;
}
// If nvram and not syncing metadata, use lightweight barrier
- if(!and_metadata && is_nvram())
+ if((kind == barrier_kind::nowait_data_only || kind == barrier_kind::wait_data_only) && is_nvram())
{
auto synced = nvram_barrier({addr, bytes});
if(synced.size() >= bytes)
@@ -209,16 +201,16 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
return {reqs.buffers};
}
}
- int flags = (wait_for_device || and_metadata) ? MS_SYNC : MS_ASYNC;
+ int flags = (kind != barrier_kind::nowait_data_only) ? MS_SYNC : MS_ASYNC;
if(-1 == ::msync(addr, bytes, flags))
{
return posix_error();
}
// Don't fsync temporary inodes
- if((_section->backing() != nullptr) && (wait_for_device || and_metadata))
+ if((_section->backing() != nullptr) && kind != barrier_kind::nowait_data_only)
{
reqs.offset += _offset;
- return _section->backing()->barrier(reqs, wait_for_device, and_metadata, d);
+ return _section->backing()->barrier(reqs, kind, d);
}
return {reqs.buffers};
}
diff --git a/include/llfio/v2.0/detail/impl/posix/utils.ipp b/include/llfio/v2.0/detail/impl/posix/utils.ipp
index 2ec36a6f..8c033899 100644
--- a/include/llfio/v2.0/detail/impl/posix/utils.ipp
+++ b/include/llfio/v2.0/detail/impl/posix/utils.ipp
@@ -24,17 +24,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../../utils.hpp"
-#ifdef __has_include
-#if __has_include("../../../quickcpplib/include/spinlock.hpp")
-#include "../../../quickcpplib/include/spinlock.hpp"
-#else
-#include "quickcpplib/include/spinlock.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/spinlock.hpp"
-#else
-#include "../../../quickcpplib/include/spinlock.hpp"
-#endif
+#include "quickcpplib/spinlock.hpp"
#include <mutex> // for lock_guard
diff --git a/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp b/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp
index a9dadf5a..7c7bc80c 100644
--- a/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp
+++ b/include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp
@@ -28,21 +28,8 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../algorithm/shared_fs_mutex/safe_byte_ranges.hpp"
-#ifdef __has_include
-#if __has_include("../../quickcpplib/include/uint128.hpp")
-#include "../../quickcpplib/include/uint128.hpp"
-#include "../../quickcpplib/include/utils/thread.hpp"
-#else
-#include "quickcpplib/include/uint128.hpp"
-#include "quickcpplib/include/utils/thread.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/uint128.hpp"
-#include "quickcpplib/include/utils/thread.hpp"
-#else
-#include "../../quickcpplib/include/uint128.hpp"
-#include "../../quickcpplib/include/utils/thread.hpp"
-#endif
+#include "quickcpplib/uint128.hpp"
+#include "quickcpplib/utils/thread.hpp"
#include <fcntl.h>
#include <sys/stat.h>
diff --git a/include/llfio/v2.0/detail/impl/storage_profile.ipp b/include/llfio/v2.0/detail/impl/storage_profile.ipp
index fb2b46ed..e1c5ec4d 100644
--- a/include/llfio/v2.0/detail/impl/storage_profile.ipp
+++ b/include/llfio/v2.0/detail/impl/storage_profile.ipp
@@ -28,17 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../storage_profile.hpp"
#include "../../utils.hpp"
-#ifdef __has_include
-#if __has_include("../../quickcpplib/include/algorithm/small_prng.hpp")
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#endif
-#elif __PCPP_ALWAYS_TRUE__
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "../../quickcpplib/include/algorithm/small_prng.hpp"
-#endif
+#include "quickcpplib/algorithm/small_prng.hpp"
#include <future>
#include <vector>
diff --git a/include/llfio/v2.0/detail/impl/windows/async_file_handle.ipp b/include/llfio/v2.0/detail/impl/windows/async_file_handle.ipp
index b0563f08..ee970a30 100644
--- a/include/llfio/v2.0/detail/impl/windows/async_file_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/windows/async_file_handle.ipp
@@ -27,10 +27,10 @@ Distributed under the Boost Software License, Version 1.0.
LLFIO_V2_NAMESPACE_BEGIN
-async_file_handle::io_result<async_file_handle::const_buffers_type> async_file_handle::barrier(async_file_handle::io_request<async_file_handle::const_buffers_type> reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept
+async_file_handle::io_result<async_file_handle::const_buffers_type> async_file_handle::barrier(async_file_handle::io_request<async_file_handle::const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept
{
// Pass through the file_handle's implementation, it understands overlapped handles
- return file_handle::barrier(reqs, wait_for_device, and_metadata, d);
+ return file_handle::barrier(reqs, kind, d);
}
template <class BuffersType, class IORoutine> result<async_file_handle::io_state_ptr> async_file_handle::_begin_io(span<char> mem, async_file_handle::operation_t operation, async_file_handle::io_request<BuffersType> reqs, async_file_handle::_erased_completion_handler &&completion, IORoutine &&ioroutine) noexcept
diff --git a/include/llfio/v2.0/detail/impl/windows/file_handle.ipp b/include/llfio/v2.0/detail/impl/windows/file_handle.ipp
index 0462051f..e8c03756 100644
--- a/include/llfio/v2.0/detail/impl/windows/file_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/windows/file_handle.ipp
@@ -294,7 +294,7 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode,
}
}
-file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(file_handle::io_request<file_handle::const_buffers_type> reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept
+file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(file_handle::io_request<file_handle::const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept
{
windows_nt_kernel::init();
using namespace windows_nt_kernel;
@@ -309,11 +309,11 @@ file_handle::io_result<file_handle::const_buffers_type> file_handle::barrier(fil
auto *isb = reinterpret_cast<IO_STATUS_BLOCK *>(&ol);
*isb = make_iostatus();
ULONG flags = 0;
- if(!wait_for_device && !and_metadata)
+ if(kind == barrier_kind::nowait_data_only)
{
- flags = 1 /*FLUSH_FLAGS_FILE_DATA_ONLY*/;
+ flags = 1 /*FLUSH_FLAGS_FILE_DATA_ONLY*/; // note this doesn't block
}
- else if(!wait_for_device)
+ else if(kind == barrier_kind::nowait_all)
{
flags = 2 /*FLUSH_FLAGS_NO_SYNC*/;
}
diff --git a/include/llfio/v2.0/detail/impl/windows/map_handle.ipp b/include/llfio/v2.0/detail/impl/windows/map_handle.ipp
index f749d45d..33ea06d9 100644
--- a/include/llfio/v2.0/detail/impl/windows/map_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/windows/map_handle.ipp
@@ -26,19 +26,8 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../../utils.hpp"
#include "import.hpp"
-#ifdef __has_include
-#if __has_include("../../../quickcpplib/include/signal_guard.hpp")
-#include "../../../quickcpplib/include/algorithm/hash.hpp"
-#include "../../../quickcpplib/include/signal_guard.hpp"
-#else
-#include "quickcpplib/include/algorithm/hash.hpp"
-#include "quickcpplib/include/signal_guard.hpp"
-#endif
-#else
-#include "quickcpplib/include/algorithm/hash.hpp"
-#include "quickcpplib/include/signal_guard.hpp"
-#endif
-
+#include "quickcpplib/algorithm/hash.hpp"
+#include "quickcpplib/signal_guard.hpp"
LLFIO_V2_NAMESPACE_BEGIN
@@ -477,7 +466,7 @@ result<void> map_handle::close() noexcept
{
if(is_writable() && (_flag & section_handle::flag::barrier_on_close))
{
- OUTCOME_TRYV(barrier({}, true, false));
+ OUTCOME_TRYV(barrier({}, barrier_kind::wait_all));
}
OUTCOME_TRYV(win32_maps_apply(_addr, _reservation, win32_map_sought::committed, [](byte *addr, size_t /* unused */) -> result<void> {
NTSTATUS ntstat = NtUnmapViewOfSection(GetCurrentProcess(), addr);
@@ -510,7 +499,7 @@ native_handle_type map_handle::release() noexcept
return {};
}
-map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_handle::io_request<map_handle::const_buffers_type> reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept
+map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_handle::io_request<map_handle::const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept
{
LLFIO_LOG_FUNCTION_CALL(this);
byte *addr = _addr + reqs.offset;
@@ -530,7 +519,7 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
bytes = _reservation - reqs.offset;
}
// If nvram and not syncing metadata, use lightweight barrier
- if(!and_metadata && is_nvram())
+ if((kind == barrier_kind::nowait_data_only || kind == barrier_kind::wait_data_only) && is_nvram())
{
auto synced = nvram_barrier({addr, bytes});
if(synced.size() >= bytes)
@@ -545,10 +534,10 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
}
return success();
}));
- if((_section != nullptr) && (_section->backing() != nullptr) && (wait_for_device || and_metadata))
+ if((_section != nullptr) && (_section->backing() != nullptr) && kind != barrier_kind::nowait_data_only)
{
reqs.offset += _offset;
- return _section->backing()->barrier(reqs, wait_for_device, and_metadata, d);
+ return _section->backing()->barrier(reqs, kind, d);
}
return {reqs.buffers};
}
diff --git a/include/llfio/v2.0/detail/impl/windows/utils.ipp b/include/llfio/v2.0/detail/impl/windows/utils.ipp
index 2b1e37f8..717386e1 100644
--- a/include/llfio/v2.0/detail/impl/windows/utils.ipp
+++ b/include/llfio/v2.0/detail/impl/windows/utils.ipp
@@ -24,7 +24,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../../../utils.hpp"
-#include "../../../quickcpplib/include/spinlock.hpp"
+#include "quickcpplib/spinlock.hpp"
#include "import.hpp"
LLFIO_V2_NAMESPACE_BEGIN
diff --git a/include/llfio/v2.0/fast_random_file_handle.hpp b/include/llfio/v2.0/fast_random_file_handle.hpp
index c5b63d25..1af381dd 100644
--- a/include/llfio/v2.0/fast_random_file_handle.hpp
+++ b/include/llfio/v2.0/fast_random_file_handle.hpp
@@ -27,7 +27,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "file_handle.hpp"
-#include "quickcpplib/include/algorithm/small_prng.hpp"
+#include "quickcpplib/algorithm/small_prng.hpp"
//! \file fast_random_file_handle.hpp Provides `fast_random_file_handle`.
@@ -271,7 +271,7 @@ public:
}
LLFIO_MAKE_FREE_FUNCTION
- LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), bool /* unused */ = false, bool /* unused */ = false, deadline /* unused */ = deadline()) noexcept override
+ LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), barrier_kind /*unused*/ = barrier_kind::nowait_data_only, deadline /* unused */ = deadline()) noexcept override
{
OUTCOME_TRY(_perms_check());
// Return null written
diff --git a/include/llfio/v2.0/file_handle.hpp b/include/llfio/v2.0/file_handle.hpp
index 084c5e78..b3a0ebc6 100644
--- a/include/llfio/v2.0/file_handle.hpp
+++ b/include/llfio/v2.0/file_handle.hpp
@@ -219,7 +219,7 @@ public:
}
LLFIO_MAKE_FREE_FUNCTION
- LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept override;
+ LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), barrier_kind kind = barrier_kind::nowait_data_only, deadline d = deadline()) noexcept override;
/*! Clone this handle (copy constructor is disabled to avoid accidental copying),
optionally race free reopening the handle with different access or caching.
@@ -293,9 +293,10 @@ public:
\param bytes The number of bytes to zero.
\param d An optional deadline by which the i/o must complete, else it is cancelled.
Note function may return significantly after this deadline if the i/o takes long to cancel.
- \errors Any of the values POSIX write() can return, `errc::timed_out`, `errc::operation_canceled`. `errc::not_supported` may be
- returned if deadline i/o is not possible with this particular handle configuration (e.g.
- writing to regular files on POSIX or writing to a non-overlapped HANDLE on Windows).
+ \errors Any of the values POSIX write() can return, `errc::timed_out`, `errc::operation_canceled`.
+ `errc::not_supported` may be returned if deadline i/o is not possible with this particular
+ handle configuration (e.g. writing to regular files on POSIX or writing to a non-overlapped
+ HANDLE on Windows).
\mallocs The default synchronous implementation in file_handle performs no memory allocation.
The asynchronous implementation in async_file_handle may perform one calloc and one free.
*/
diff --git a/include/llfio/v2.0/fs_handle.hpp b/include/llfio/v2.0/fs_handle.hpp
index f3b816b6..0104c312 100644
--- a/include/llfio/v2.0/fs_handle.hpp
+++ b/include/llfio/v2.0/fs_handle.hpp
@@ -28,7 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "path_handle.hpp"
#include "path_view.hpp"
-#include "quickcpplib/include/uint128.hpp"
+#include "quickcpplib/uint128.hpp"
//! \file fs_handle.hpp Provides fs_handle
@@ -74,7 +74,9 @@ protected:
{
}
//! Implicit move construction of fs_handle permitted
- constexpr fs_handle(fs_handle &&o) noexcept : _devid(o._devid), _inode(o._inode)
+ constexpr fs_handle(fs_handle &&o) noexcept
+ : _devid(o._devid)
+ , _inode(o._inode)
{
o._devid = 0;
o._inode = 0;
@@ -142,8 +144,8 @@ public:
LLFIO_HEADERS_ONLY_VIRTUAL_SPEC result<path_handle> parent_path_handle(deadline d = std::chrono::seconds(30)) const noexcept;
/*! Relinks the current path of this open handle to the new path specified. If `atomic_replace` is
- true, the relink \b atomically and silently replaces any item at the new path specified. This operation
- is both atomic and silent matching POSIX behaviour even on Microsoft Windows where
+ true, the relink \b atomically and silently replaces any item at the new path specified. This
+ operation is both atomic and silent matching POSIX behaviour even on Microsoft Windows where
no Win32 API can match POSIX semantics.
\warning Some operating systems provide a race free syscall for renaming an open handle (Windows).
@@ -168,11 +170,55 @@ public:
LLFIO_HEADERS_ONLY_VIRTUAL_SPEC
result<void> relink(const path_handle &base, path_view_type path, bool atomic_replace = true, deadline d = std::chrono::seconds(30)) noexcept;
- /*! Unlinks the current path of this open handle, causing its entry to immediately disappear from the filing system.
- On Windows before Windows 10 1709 unless `flag::win_disable_unlink_emulation` is set, this behaviour is
- simulated by renaming the file to something random and setting its delete-on-last-close flag.
- Note that Windows may prevent the renaming of a file in use by another process, if so it will
- NOT be renamed.
+#if 0 // Not implemented yet for absolutely no good reason
+ /*! Links the inode referred to by this open handle to the path specified. The current path
+ of this open handle is not changed, unless it has no current path due to being unlinked.
+
+ \warning Some operating systems provide a race free syscall for linking an open handle to a new
+ location (Linux, Windows).
+ On all other operating systems this call is \b racy and can result in the wrong inode being
+ linked. Note that unless `flag::disable_safety_unlinks` is set, this implementation opens a
+ `path_handle` to the source containing directory first, then checks before linking that the item
+ about to be hard linked has the same inode as the open file handle. It will retry this matching
+ until success until the deadline given. This should prevent most unmalicious accidental loss of
+ data.
+
+ \param base Base for any relative path.
+ \param path The relative or absolute new path to hard link to.
+ \param d The deadline by which the matching of the containing directory to the open handle's inode
+ must succeed, else `errc::timed_out` will be returned.
+ \mallocs Except on platforms with race free syscalls for renaming open handles (Windows), calls
+ `current_path()` via `parent_path_handle()` and thus is both expensive and calls malloc many times.
+ */
+ LLFIO_MAKE_FREE_FUNCTION
+ LLFIO_HEADERS_ONLY_VIRTUAL_SPEC
+ result<void> link(const path_handle &base, path_view_type path, deadline d = std::chrono::seconds(30)) noexcept;
+
+ /*! Clones the inode referenced by the open handle into a new inode referencing the same extents
+ for the file content, with a copy of the same metadata, apart from ownership which is for the
+ current user. Changes to either inode are guaranteed to not be seen by the other inode i.e. they
+ become completely independent, even though they initially reference the same file content extents.
+ If your filing system supports this call (at the time of writing - Linux: XFS, btrfs, ocfs2, smbfs;
+ Mac OS: APFS; Windows: ReFS, CIFS), this is a very cheap way of copying even very large files.
+ Be aware that on Samba/CIFS, rather than erroring out if the storage filesystem doesn't implement
+ support, this call is implemented by having the remove machine perform the file
+ copy, which is usually much faster than doing the copy over the network.
+
+ \return A file handle instance referring to the cloned inode.
+ \param base Base for any relative path.
+ \param path The relative or absolute new path to clone the inode to.
+ */
+ LLFIO_MAKE_FREE_FUNCTION
+ LLFIO_HEADERS_ONLY_VIRTUAL_SPEC
+ result<file_handle> clone_inode(const path_handle &base,
+ path_view_type path) noexcept;
+#endif
+
+ /*! Unlinks the current path of this open handle, causing its entry to immediately disappear
+ from the filing system. On Windows before Windows 10 1709 unless
+ `flag::win_disable_unlink_emulation` is set, this behaviour is simulated by renaming the file
+ to something random and setting its delete-on-last-close flag. Note that Windows may prevent
+ the renaming of a file in use by another process, if so it will NOT be renamed.
After the next handle to that file closes, it will become permanently unopenable by anyone
else until the last handle is closed, whereupon the entry will be eventually removed by the
operating system.
diff --git a/include/llfio/v2.0/handle.hpp b/include/llfio/v2.0/handle.hpp
index 26b8ff22..a99887b0 100644
--- a/include/llfio/v2.0/handle.hpp
+++ b/include/llfio/v2.0/handle.hpp
@@ -242,8 +242,8 @@ public:
(deleted) path for file inodes no longer cached by the kernel path cache, LLFIO cannot
detect the difference. FreeBSD will also return any path leading to the inode if it is
hard linked. FreeBSD does implement path retrieval for directory inodes
- correctly however, and see `algorithm::stablized_path<T>` for a handle adapter which
- makes use of that.
+ correctly however, and see `algorithm::cached_parent_handle_adapter<T>` for a handle
+ adapter which makes use of that.
On Linux if `/proc` is not mounted, this call fails with an error. All APIs in LLFIO
which require the use of `current_path()` can be told to not use it e.g. `flag::disable_safety_unlinks`.
diff --git a/include/llfio/v2.0/io_handle.hpp b/include/llfio/v2.0/io_handle.hpp
index c454254d..7155d8a2 100644
--- a/include/llfio/v2.0/io_handle.hpp
+++ b/include/llfio/v2.0/io_handle.hpp
@@ -50,6 +50,15 @@ public:
using caching = handle::caching;
using flag = handle::flag;
+ //! The kinds of write reordering barrier which can be performed.
+ enum class barrier_kind
+ {
+ nowait_data_only, //!< Barrier data only, non-blocking. This is highly optimised on NV-DIMM storage, but consider using `nvram_barrier()` for even better performance.
+ wait_data_only, //!< Barrier data only, block until it is done. This is highly optimised on NV-DIMM storage, but consider using `nvram_barrier()` for even better performance.
+ nowait_all, //!< Barrier data and the metadata to retrieve it, non-blocking.
+ wait_all //!< Barrier data and the metadata to retrieve it, block until it is done.
+ };
+
//! The scatter buffer type used by this handle. Guaranteed to be `TrivialType` and `StandardLayoutType`.
//! Try to make address and length 64 byte, or ideally, `page_size()` aligned where possible.
struct buffer_type
@@ -68,7 +77,11 @@ public:
//! Default constructor
buffer_type() = default;
//! Constructor
- constexpr buffer_type(pointer data, size_type len) noexcept : _data(data), _len(len) {}
+ constexpr buffer_type(pointer data, size_type len) noexcept
+ : _data(data)
+ , _len(len)
+ {
+ }
buffer_type(const buffer_type &) = default;
buffer_type(buffer_type &&) = default;
buffer_type &operator=(const buffer_type &) = default;
@@ -96,6 +109,7 @@ public:
constexpr const_iterator end() const noexcept { return _data + _len; }
//! Returns an iterator to after the end of the buffer
constexpr const_iterator cend() const noexcept { return _data + _len; }
+
private:
friend constexpr inline void _check_iovec_match();
pointer _data;
@@ -119,9 +133,17 @@ public:
//! Default constructor
const_buffer_type() = default;
//! Constructor
- constexpr const_buffer_type(pointer data, size_type len) noexcept : _data(data), _len(len) {}
+ constexpr const_buffer_type(pointer data, size_type len) noexcept
+ : _data(data)
+ , _len(len)
+ {
+ }
//! Converting constructor from non-const buffer type
- constexpr const_buffer_type(buffer_type b) noexcept : _data(b.data()), _len(b.size()) {}
+ constexpr const_buffer_type(buffer_type b) noexcept
+ : _data(b.data())
+ , _len(b.size())
+ {
+ }
const_buffer_type(const const_buffer_type &) = default;
const_buffer_type(const_buffer_type &&) = default;
const_buffer_type &operator=(const const_buffer_type &) = default;
@@ -149,6 +171,7 @@ public:
constexpr const_iterator end() const noexcept { return _data + _len; }
//! Returns an iterator to after the end of the buffer
constexpr const_iterator cend() const noexcept { return _data + _len; }
+
private:
pointer _data;
size_type _len;
@@ -197,7 +220,7 @@ public:
// static_assert(std::is_trivially_move_assignable<io_request<buffers_type>>::value, "io_request<buffers_type> is not trivially move assignable!");
static_assert(std::is_standard_layout<io_request<buffers_type>>::value, "io_request<buffers_type> is not a standard layout type!");
#endif
- //! The i/o result type used by this handle. Guaranteed to be `TrivialType` apart from construction..
+ //! The i/o result type used by this handle. Guaranteed to be `TrivialType` apart from construction.
template <class T> struct io_result : public LLFIO_V2_NAMESPACE::result<T>
{
using Base = LLFIO_V2_NAMESPACE::result<T>;
@@ -265,7 +288,10 @@ public:
{
}
//! Explicit conversion from handle permitted
- explicit constexpr io_handle(handle &&o) noexcept : handle(std::move(o)) {}
+ explicit constexpr io_handle(handle &&o) noexcept
+ : handle(std::move(o))
+ {
+ }
//! Move construction permitted
io_handle(io_handle &&) = default;
//! No copy construction (use `clone()`)
@@ -275,8 +301,8 @@ public:
//! No copy assignment
io_handle &operator=(const io_handle &) = delete;
- /*! \brief The *maximum* number of buffers which a single read or write syscall can process at a time
- for this specific open handle. On POSIX, this is known as `IOV_MAX`.
+ /*! \brief The *maximum* number of buffers which a single read or write syscall can process at a
+ time for this specific open handle. On POSIX, this is known as `IOV_MAX`.
Note that the actual number of buffers accepted for a read or a write may be significantly
lower than this system-defined limit, depending on available resources. The `read()` or `write()`
@@ -286,8 +312,11 @@ public:
but other OSs do not. Some OSs guarantee that each i/o syscall has effects atomically visible or not
to other i/o, other OSs do not.
- Microsoft Windows and OS X does not implement scatter-gather file i/o syscalls.
+ OS X does not implement scatter-gather file i/o syscalls.
Thus this function will always return `1` in that situation.
+
+ Microsoft Windows *may* implement scatter-gather file i/o under very limited circumstances.
+ Most of the time this function will return `1`.
*/
LLFIO_HEADERS_ONLY_VIRTUAL_SPEC size_t max_buffers() const noexcept;
@@ -350,39 +379,36 @@ public:
return std::move(ret).error();
}
- /*! \brief Issue a write reordering barrier such that writes preceding the barrier will reach storage
- before writes after this barrier.
+ /*! \brief Issue a write reordering barrier such that writes preceding the barrier will reach
+ storage before writes after this barrier.
- \warning **Assume that this call is a no-op**. It is not reliably implemented in many common use cases,
- for example if your code is running inside a LXC container, or if the user has mounted the filing
- system with non-default options. Instead open the handle with `caching::reads` which means that all
- writes form a strict sequential order not completing until acknowledged by the storage device.
- Filing system can and do use different algorithms to give much better performance with `caching::reads`,
- some (e.g. ZFS) spectacularly better.
+ \warning **Assume that this call is a no-op**. It is not reliably implemented in many common
+ use cases, for example if your code is running inside a LXC container, or if the user has mounted
+ the filing system with non-default options. Instead open the handle with `caching::reads` which
+ means that all writes form a strict sequential order not completing until acknowledged by the
+ storage device. Filing system can and do use different algorithms to give much better performance
+ with `caching::reads`, some (e.g. ZFS) spectacularly better.
- \warning Let me repeat again: consider this call to be a **hint** to poke the kernel with a stick to
- go start to do some work sooner rather than later. **It may be ignored entirely**.
+ \warning Let me repeat again: consider this call to be a **hint** to poke the kernel with a stick
+ to go start to do some work sooner rather than later. **It may be ignored entirely**.
\warning For portability, you can only assume that barriers write order for a single handle
- instance. You cannot assume that barriers write order across multiple handles to the same inode, or
- across processes.
+ instance. You cannot assume that barriers write order across multiple handles to the same inode,
+ or across processes.
\return The buffers barriered, which may not be the buffers input. The size of each scatter-gather
buffer is updated with the number of bytes of that buffer barriered.
- \param reqs A scatter-gather and offset request for what range to barrier. May be ignored on some platforms
- which always write barrier the entire file. Supplying a default initialised reqs write barriers the entire file.
- \param wait_for_device True if you want the call to wait until data reaches storage and that storage
- has acknowledged the data is physically written. Slow.
- \param and_metadata True if you want the call to sync the metadata for retrieving the writes before the
- barrier after a sudden power loss event. Slow. Setting this to false enables much faster performance,
- especially on non-volatile memory.
+ \param reqs A scatter-gather and offset request for what range to barrier. May be ignored on
+ some platforms which always write barrier the entire file. Supplying a default initialised reqs
+ write barriers the entire file.
+ \param kind Which kind of write reordering barrier to perform.
\param d An optional deadline by which the i/o must complete, else it is cancelled.
Note function may return significantly after this deadline if the i/o takes long to cancel.
\errors Any of the values POSIX fdatasync() or Windows NtFlushBuffersFileEx() can return.
\mallocs None.
*/
LLFIO_MAKE_FREE_FUNCTION
- virtual io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept = 0;
+ virtual io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), barrier_kind kind = barrier_kind::nowait_data_only, deadline d = deadline()) noexcept = 0;
/*! \class extent_guard
\brief RAII holder a locked extent of bytes in a file.
@@ -410,7 +436,14 @@ public:
//! Default constructor
constexpr extent_guard() {} // NOLINT
//! Move constructor
- extent_guard(extent_guard &&o) noexcept : _h(o._h), _offset(o._offset), _length(o._length), _exclusive(o._exclusive) { o.release(); }
+ extent_guard(extent_guard &&o) noexcept
+ : _h(o._h)
+ , _offset(o._offset)
+ , _length(o._length)
+ , _exclusive(o._exclusive)
+ {
+ o.release();
+ }
//! Move assign
extent_guard &operator=(extent_guard &&o) noexcept
{
@@ -461,23 +494,25 @@ public:
}
};
- /*! \brief Tries to lock the range of bytes specified for shared or exclusive access. Be aware this passes through
- the same semantics as the underlying OS call, including any POSIX insanity present on your platform:
+ /*! \brief Tries to lock the range of bytes specified for shared or exclusive access. Be aware
+ this passes through the same semantics as the underlying OS call, including any POSIX insanity
+ present on your platform:
- Any fd closed on an inode must release all byte range locks on that inode for all
- other fds. If your OS isn't new enough to support the non-insane lock API, `flag::byte_lock_insanity` will be set
- in flags() after the first call to this function.
+ other fds. If your OS isn't new enough to support the non-insane lock API,
+ `flag::byte_lock_insanity` will be set in flags() after the first call to this function.
- Threads replace each other's locks, indeed locks replace each other's locks.
You almost cetainly should use your choice of an `algorithm::shared_fs_mutex::*` instead of this
as those are more portable and performant.
- \warning This is a low-level API which you should not use directly in portable code. Another issue is that
- atomic lock upgrade/downgrade, if your platform implements that (you should assume it does not in
- portable code), means that on POSIX you need to *release* the old `extent_guard` after creating a new one over the
- same byte range, otherwise the old `extent_guard`'s destructor will simply unlock the range entirely. On
- Windows however upgrade/downgrade locks overlay, so on that platform you must *not* release the old
- `extent_guard`. Look into `algorithm::shared_fs_mutex::safe_byte_ranges` for a portable solution.
+ \warning This is a low-level API which you should not use directly in portable code. Another
+ issue is that atomic lock upgrade/downgrade, if your platform implements that (you should assume
+ it does not in portable code), means that on POSIX you need to *release* the old `extent_guard`
+ after creating a new one over the same byte range, otherwise the old `extent_guard`'s destructor
+ will simply unlock the range entirely. On Windows however upgrade/downgrade locks overlay, so on
+ that platform you must *not* release the old `extent_guard`. Look into
+ `algorithm::shared_fs_mutex::safe_byte_ranges` for a portable solution.
\return An extent guard, the destruction of which will call unlock().
\param offset The offset to lock. Note that on POSIX the top bit is always cleared before use
@@ -594,42 +629,6 @@ inline io_handle::io_result<io_handle::size_type> write(io_handle &self, io_hand
{
return self.write(std::forward<decltype(offset)>(offset), std::forward<decltype(lst)>(lst), std::forward<decltype(d)>(d));
}
-/*! \brief Issue a write reordering barrier such that writes preceding the barrier will reach storage
-before writes after this barrier.
-
-\warning **Assume that this call is a no-op**. It is not reliably implemented in many common use cases,
-for example if your code is running inside a LXC container, or if the user has mounted the filing
-system with non-default options. Instead open the handle with `caching::reads` which means that all
-writes form a strict sequential order not completing until acknowledged by the storage device.
-Filing system can and do use different algorithms to give much better performance with `caching::reads`,
-some (e.g. ZFS) spectacularly better.
-
-\warning Let me repeat again: consider this call to be a **hint** to poke the kernel with a stick to
-go start to do some work sooner rather than later. **It may be ignored entirely**.
-
-\warning For portability, you can only assume that barriers write order for a single handle
-instance. You cannot assume that barriers write order across multiple handles to the same inode, or
-across processes.
-
-\return The buffers barriered, which may not be the buffers input. The size of each scatter-gather
-buffer is updated with the number of bytes of that buffer barriered.
-\param self The object whose member function to call.
-\param reqs A scatter-gather and offset request for what range to barrier. May be ignored on some platforms
-which always write barrier the entire file. Supplying a default initialised reqs write barriers the entire file.
-\param wait_for_device True if you want the call to wait until data reaches storage and that storage
-has acknowledged the data is physically written. Slow.
-\param and_metadata True if you want the call to sync the metadata for retrieving the writes before the
-barrier after a sudden power loss event. Slow. Setting this to false enables much faster performance,
-especially on non-volatile memory.
-\param d An optional deadline by which the i/o must complete, else it is cancelled.
-Note function may return significantly after this deadline if the i/o takes long to cancel.
-\errors Any of the values POSIX fdatasync() or Windows NtFlushBuffersFileEx() can return.
-\mallocs None.
-*/
-inline io_handle::io_result<io_handle::const_buffers_type> barrier(io_handle &self, io_handle::io_request<io_handle::const_buffers_type> reqs = io_handle::io_request<io_handle::const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept
-{
- return self.barrier(std::forward<decltype(reqs)>(reqs), std::forward<decltype(wait_for_device)>(wait_for_device), std::forward<decltype(and_metadata)>(and_metadata), std::forward<decltype(d)>(d));
-}
// END make_free_functions.py
LLFIO_V2_NAMESPACE_END
diff --git a/include/llfio/v2.0/llfio.hpp b/include/llfio/v2.0/llfio.hpp
index a33318af..3739865f 100644
--- a/include/llfio/v2.0/llfio.hpp
+++ b/include/llfio/v2.0/llfio.hpp
@@ -62,27 +62,30 @@ import LLFIO_MODULE_NAME;
#include "stat.hpp"
#include "utils.hpp"
-#ifndef LLFIO_LEAN_AND_MEAN
+#ifdef LLFIO_INCLUDE_ASYNC_FILE_HANDLE
#include "async_file_handle.hpp"
#else
#include "file_handle.hpp"
#endif
#include "directory_handle.hpp"
-#include "mapped.hpp"
#include "statfs.hpp"
-#ifndef LLFIO_LEAN_AND_MEAN
+#ifdef LLFIO_INCLUDE_STORAGE_PROFILE
#include "storage_profile.hpp"
#endif
#include "fast_random_file_handle.hpp"
#include "symlink_handle.hpp"
#include "algorithm/handle_adapter/cached_parent.hpp"
-#include "algorithm/handle_adapter/xor.hpp"
#include "algorithm/shared_fs_mutex/atomic_append.hpp"
#include "algorithm/shared_fs_mutex/byte_ranges.hpp"
#include "algorithm/shared_fs_mutex/lock_files.hpp"
-#include "algorithm/shared_fs_mutex/memory_map.hpp"
#include "algorithm/shared_fs_mutex/safe_byte_ranges.hpp"
+
+#ifndef LLFIO_EXCLUDE_MAPPED_FILE_HANDLE
+#include "mapped.hpp"
+#include "algorithm/handle_adapter/xor.hpp"
+#include "algorithm/shared_fs_mutex/memory_map.hpp"
#include "algorithm/trivial_vector.hpp"
+#endif
#endif
diff --git a/include/llfio/v2.0/map_handle.hpp b/include/llfio/v2.0/map_handle.hpp
index d4c75b1d..906764af 100644
--- a/include/llfio/v2.0/map_handle.hpp
+++ b/include/llfio/v2.0/map_handle.hpp
@@ -456,7 +456,7 @@ public:
//! Releases the mapped view, but does NOT release the native handle.
LLFIO_HEADERS_ONLY_VIRTUAL_SPEC native_handle_type release() noexcept override;
LLFIO_MAKE_FREE_FUNCTION
- LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept override;
+ LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), barrier_kind kind = barrier_kind::nowait_data_only, deadline d = deadline()) noexcept override;
/*! Map unused memory into view, creating new memory if insufficient unused memory is available. Note that the memory mapped by this call may contain non-zero bits (recycled memory) unless `zeroed` is true.
\param bytes How many bytes to map. Typically will be rounded up to a multiple of the page size (see `page_size()`).
@@ -730,10 +730,6 @@ inline result<void> close(map_handle &self) noexcept
{
return self.close();
}
-inline map_handle::io_result<map_handle::const_buffers_type> barrier(map_handle &self, map_handle::io_request<map_handle::const_buffers_type> reqs = map_handle::io_request<map_handle::const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept
-{
- return self.barrier(std::forward<decltype(reqs)>(reqs), std::forward<decltype(wait_for_device)>(wait_for_device), std::forward<decltype(and_metadata)>(and_metadata), std::forward<decltype(d)>(d));
-}
/*! Create new memory and map it into view.
\param bytes How many bytes to create and map. Typically will be rounded up to a multiple of the page size (see `page_size()`) on POSIX, 64Kb on Windows.
\param zeroed Set to true if only all bits zeroed memory is wanted.
diff --git a/include/llfio/v2.0/mapped_file_handle.hpp b/include/llfio/v2.0/mapped_file_handle.hpp
index 969ce864..41df2253 100644
--- a/include/llfio/v2.0/mapped_file_handle.hpp
+++ b/include/llfio/v2.0/mapped_file_handle.hpp
@@ -327,7 +327,7 @@ public:
}
LLFIO_HEADERS_ONLY_VIRTUAL_SPEC result<void> close() noexcept override;
LLFIO_HEADERS_ONLY_VIRTUAL_SPEC native_handle_type release() noexcept override;
- LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept override { return _mh.barrier(reqs, wait_for_device, and_metadata, d); }
+ LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), barrier_kind kind = barrier_kind::nowait_data_only, deadline d = deadline()) noexcept override { return _mh.barrier(reqs, kind, d); }
result<mapped_file_handle> clone(size_type reservation, mode mode_ = mode::unchanged, caching caching_ = caching::unchanged, deadline d = std::chrono::seconds(30)) const noexcept
{
OUTCOME_TRY(fh, file_handle::clone(mode_, caching_, d));
diff --git a/include/llfio/v2.0/outcome b/include/llfio/v2.0/outcome
-Subproject 2954530fd4556c59c7e2f9696b42af4a952e9ee
+Subproject 90769c82ee9c1c11eef83d700108dfe3685a1cd
diff --git a/include/llfio/v2.0/path_discovery.hpp b/include/llfio/v2.0/path_discovery.hpp
index 613a14b9..c68200b2 100644
--- a/include/llfio/v2.0/path_discovery.hpp
+++ b/include/llfio/v2.0/path_discovery.hpp
@@ -99,7 +99,7 @@ namespace path_discovery
This is implemented by iterating all of the paths returned by `verified_temporary_directories()`
and checking what file system is in use. The following regex is used:
- `btrfs|cifs|exfat|ext?|f2fs|hfs|jfs|lxfs|nfs|nilf2|ufs|vfat|xfs|zfs|msdosfs|newnfs|ntfs|smbfs|unionfs|fat|fat32`
+ `btrfs|cifs|exfat|ext(2|3|4)|f2fs|hfs|jfs|lxfs|nfs|nilf2|ufs|vfat|xfs|zfs|msdosfs|newnfs|ntfs|smbfs|unionfs|fat|fat32`
The handle is created during `verified_temporary_directories()` and is statically cached thereafter.
*/
diff --git a/include/llfio/v2.0/quickcpplib b/include/llfio/v2.0/quickcpplib
-Subproject f744cf9d0142596d71c96a82e2b5d0b6855e56b
+Subproject c035910c060880c9391ceb6af414bdef632df0c
diff --git a/include/llfio/v2.0/status_code.hpp b/include/llfio/v2.0/status_code.hpp
index e9296fc2..03c3c4c9 100644
--- a/include/llfio/v2.0/status_code.hpp
+++ b/include/llfio/v2.0/status_code.hpp
@@ -55,8 +55,8 @@ as that (a) enables safe header only LLFIO on Windows (b) produces better codege
#if LLFIO_EXPERIMENTAL_STATUS_CODE
// Bring in a result implementation based on status_code
-#include "outcome/include/outcome/experimental/status_result.hpp"
-#include "outcome/include/outcome/try.hpp"
+#include "outcome/experimental/status_result.hpp"
+#include "outcome/try.hpp"
LLFIO_V2_NAMESPACE_BEGIN
@@ -338,7 +338,9 @@ LLFIO_V2_NAMESPACE_END
// Bring in a result implementation based on std::error_code
-#include "outcome/include/outcome.hpp"
+#include "outcome/result.hpp"
+#include "outcome/try.hpp"
+#include "outcome/utils.hpp"
LLFIO_V2_NAMESPACE_BEGIN
@@ -553,7 +555,6 @@ inline void error_info::throw_exception() const
}
template <class T> using result = OUTCOME_V2_NAMESPACE::result<T, error_info>;
-template <class T> using outcome = OUTCOME_V2_NAMESPACE::outcome<T, error_info>;
using OUTCOME_V2_NAMESPACE::failure;
using OUTCOME_V2_NAMESPACE::success;
inline error_info error_from_exception(std::exception_ptr &&ep = std::current_exception(), std::error_code not_matched = std::make_error_code(std::errc::resource_unavailable_try_again)) noexcept
diff --git a/include/llfio/v2.0/storage_profile.hpp b/include/llfio/v2.0/storage_profile.hpp
index 902621bb..80ebf32a 100644
--- a/include/llfio/v2.0/storage_profile.hpp
+++ b/include/llfio/v2.0/storage_profile.hpp
@@ -28,10 +28,15 @@ Distributed under the Boost Software License, Version 1.0.
#include "io_service.hpp"
#if LLFIO_EXPERIMENTAL_STATUS_CODE
-#include "outcome/include/outcome/experimental/status_outcome.hpp"
+#include "outcome/experimental/status_outcome.hpp"
LLFIO_V2_NAMESPACE_EXPORT_BEGIN
template <class T> using outcome = OUTCOME_V2_NAMESPACE::experimental::status_outcome<T, file_io_error>;
LLFIO_V2_NAMESPACE_END
+#else
+#include "outcome/outcome.hpp"
+LLFIO_V2_NAMESPACE_EXPORT_BEGIN
+template <class T> using outcome = OUTCOME_V2_NAMESPACE::outcome<T, error_info>;
+LLFIO_V2_NAMESPACE_END
#endif
#include <regex>
diff --git a/include/llfio/v2.0/utils.hpp b/include/llfio/v2.0/utils.hpp
index 751984a6..370a03a9 100644
--- a/include/llfio/v2.0/utils.hpp
+++ b/include/llfio/v2.0/utils.hpp
@@ -30,7 +30,7 @@ Distributed under the Boost Software License, Version 1.0.
#endif
#include "config.hpp"
-#include "quickcpplib/include/algorithm/string.hpp"
+#include "quickcpplib/algorithm/string.hpp"
//! \file utils.hpp Provides namespace utils
diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt
index f14b4bed..7e4f63bc 100644
--- a/programs/CMakeLists.txt
+++ b/programs/CMakeLists.txt
@@ -38,7 +38,7 @@ function(make_program program)
endfunction()
make_program(benchmark-iostreams llfio::hl)
-make_program(benchmark-locking llfio::hl)
+make_program(benchmark-locking llfio::hl kerneltest::hl)
make_program(fs-probe llfio::hl)
make_program(illegal-codepoints llfio::hl)
make_program(key-value-store llfio::hl)
diff --git a/programs/benchmark-iostreams/main.cpp b/programs/benchmark-iostreams/main.cpp
index 2592c920..53606c5f 100644
--- a/programs/benchmark-iostreams/main.cpp
+++ b/programs/benchmark-iostreams/main.cpp
@@ -27,11 +27,7 @@ Distributed under the Boost Software License, Version 1.0.
#define REGIONSIZE (100 * 1024 * 1024)
#include "../../include/llfio/llfio.hpp"
-#if __has_include("quickcpplib/include/algorithm/small_prng.hpp")
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "../../include/llfio/v2.0/quickcpplib/include/algorithm/small_prng.hpp"
-#endif
+#include "quickcpplib/algorithm/small_prng.hpp"
#include <chrono>
#include <fstream>
@@ -151,7 +147,7 @@ int main()
auto th = llfio::file({}, "testfile", llfio::file_handle::mode::write, llfio::file_handle::creation::if_needed).value();
std::vector<char> buffer(REGIONSIZE, 'a');
th.write(0, {{(llfio::byte *) buffer.data(), buffer.size()}}).value();
- th.barrier({}, true, true).value();
+ th.barrier({}, llfio::file_handle::barrier_kind::wait_all).value();
}
{
auto begin = nanoclock();
diff --git a/programs/benchmark-locking/main.cpp b/programs/benchmark-locking/main.cpp
index 531ce780..8eaa204b 100644
--- a/programs/benchmark-locking/main.cpp
+++ b/programs/benchmark-locking/main.cpp
@@ -31,7 +31,7 @@ Distributed under the Boost Software License, Version 1.0.
#define _CRT_SECURE_NO_WARNINGS 1
#include "../../include/llfio/llfio.hpp"
-#include "kerneltest/include/kerneltest/v1.0/child_process.hpp"
+#include "kerneltest/v1.0/child_process.hpp"
#include <fstream>
#include <iostream>
diff --git a/programs/fs-probe/main.cpp b/programs/fs-probe/main.cpp
index 2ef117ae..db1a11a1 100644
--- a/programs/fs-probe/main.cpp
+++ b/programs/fs-probe/main.cpp
@@ -23,8 +23,10 @@ Distributed under the Boost Software License, Version 1.0.
*/
#define _CRT_SECURE_NO_WARNINGS 1
+#define LLFIO_INCLUDE_STORAGE_PROFILE 1
#include "../../include/llfio/llfio.hpp"
+#include "outcome/iostream_support.hpp"
#include <fstream>
#include <iomanip>
diff --git a/programs/key-value-store/include/key_value_store.hpp b/programs/key-value-store/include/key_value_store.hpp
index 2740ce06..8ec30836 100644
--- a/programs/key-value-store/include/key_value_store.hpp
+++ b/programs/key-value-store/include/key_value_store.hpp
@@ -26,11 +26,7 @@ Distributed under the Boost Software License, Version 1.0.
#define KEY_VALUE_STORE_HPP
#include "../../../include/llfio/llfio.hpp"
-#if __has_include("quickcpplib/include/algorithm/open_hash_index.hpp")
-#include "quickcpplib/include/algorithm/open_hash_index.hpp"
-#else
-#include "../../../include/llfio/v2.0/quickcpplib/include/algorithm/open_hash_index.hpp"
-#endif
+#include "quickcpplib/algorithm/open_hash_index.hpp"
#include <vector>
diff --git a/programs/key-value-store/main.cpp b/programs/key-value-store/main.cpp
index c7d921a6..c6de6d08 100644
--- a/programs/key-value-store/main.cpp
+++ b/programs/key-value-store/main.cpp
@@ -24,6 +24,8 @@ Distributed under the Boost Software License, Version 1.0.
#include "include/key_value_store.hpp"
+#include <iostream>
+
namespace stackoverflow
{
namespace filesystem = LLFIO_V2_NAMESPACE::filesystem;
diff --git a/test/kerneltest b/test/kerneltest
-Subproject 08da4697da766ff20eecc018b2892eb39314adc
+Subproject 489ff59aa243c748126961ed9f7fb237af6d4ca
diff --git a/test/test_kernel_decl.hpp b/test/test_kernel_decl.hpp
index 95fde2b3..39abd98f 100644
--- a/test/test_kernel_decl.hpp
+++ b/test/test_kernel_decl.hpp
@@ -36,14 +36,14 @@ Distributed under the Boost Software License, Version 1.0.
#if LLFIO_EXPERIMENTAL_STATUS_CODE
#define KERNELTEST_EXPERIMENTAL_STATUS_CODE 1
-#include "outcome/include/outcome/experimental/status-code/include/iostream_support.hpp"
+#include "outcome/experimental/status-code/include/iostream_support.hpp"
// Used for initialiser list stored results as the erased form is move-only
template <class T> using il_result = OUTCOME_V2_NAMESPACE::experimental::status_result<T, SYSTEM_ERROR2_NAMESPACE::generic_code>;
#else
template <class T> using il_result = LLFIO_V2_NAMESPACE::result<T>;
#endif
-#include "kerneltest/include/kerneltest.hpp"
+#include "kerneltest//kerneltest.hpp"
#if 0
// Tell KernelTest's outcome how to grok LLFIO's result
diff --git a/test/tests/fast_random_file_handle.cpp b/test/tests/fast_random_file_handle.cpp
index d528c44f..60cd34b3 100644
--- a/test/tests/fast_random_file_handle.cpp
+++ b/test/tests/fast_random_file_handle.cpp
@@ -24,15 +24,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../test_kernel_decl.hpp"
-#ifdef __has_include
-#if __has_include("../../../include/llfio/v2.0/quickcpplib/include/algorithm/small_prng.hpp")
-#include "../../../include/llfio/v2.0/quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#endif
-#else
-#include "../../../include/llfio/v2.0/quickcpplib/include/algorithm/small_prng.hpp"
-#endif
+#include "quickcpplib/algorithm/small_prng.hpp"
static inline void TestFastRandomFileHandleWorks()
diff --git a/test/tests/handle_adapter_xor.cpp b/test/tests/handle_adapter_xor.cpp
index de1d1d91..39a451d5 100644
--- a/test/tests/handle_adapter_xor.cpp
+++ b/test/tests/handle_adapter_xor.cpp
@@ -24,16 +24,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../test_kernel_decl.hpp"
-#ifdef __has_include
-#if __has_include("../../../include/llfio/v2.0/quickcpplib/include/algorithm/small_prng.hpp")
-#include "../../../include/llfio/v2.0/quickcpplib/include/algorithm/small_prng.hpp"
-#else
-#include "quickcpplib/include/algorithm/small_prng.hpp"
-#endif
-#else
-#include "../../../include/llfio/v2.0/quickcpplib/include/algorithm/small_prng.hpp"
-#endif
-
+#include "quickcpplib/algorithm/small_prng.hpp"
static inline void TestXorHandleAdapterWorks()
{