diff options
-rw-r--r-- | Readme.md | 1 | ||||
-rw-r--r-- | include/afio/revision.hpp | 6 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/posix/file_handle.ipp | 10 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/posix/fs_handle.ipp | 20 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/windows/directory_handle.ipp | 8 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/windows/file_handle.ipp | 9 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/windows/fs_handle.ipp | 6 | ||||
-rw-r--r-- | include/afio/v2.0/fs_handle.hpp | 28 |
8 files changed, 48 insertions, 40 deletions
@@ -16,6 +16,7 @@ Tarballs of source and prebuilt binaries for Linux x64, MacOS x64 and Windows x6 - [ ] Add OS X support to `storage_profile`, this should complete the Mac OS port. - [x] Fix all known bugs in Outcome, plus reorg source code in prep for `status_code`. - [x] Scatter-gather buffers to use https://github.com/martinmoene/byte-lite +- [x] Make lazy the stat fetch during file/dir open. - [ ] Implement SG14 `status_code` as a standalone library and test in AFIO. - [ ] Single include generation now we're on `status_code` and it's safe. - [ ] `atomic_append` isn't actually being tested in shared_fs_mutex diff --git a/include/afio/revision.hpp b/include/afio/revision.hpp index e7e3feb9..89a13ea0 100644 --- a/include/afio/revision.hpp +++ b/include/afio/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 AFIO_PREVIOUS_COMMIT_REF 4e837be97c2972e11a8515ae260e4476bd6654e3 -#define AFIO_PREVIOUS_COMMIT_DATE "2018-04-11 11:25:46 +00:00" -#define AFIO_PREVIOUS_COMMIT_UNIQUE 4e837be9 +#define AFIO_PREVIOUS_COMMIT_REF bb5b4123ccd90798ae4957a611c3725f5239ebd4 +#define AFIO_PREVIOUS_COMMIT_DATE "2018-04-14 16:37:23 +00:00" +#define AFIO_PREVIOUS_COMMIT_UNIQUE bb5b4123 diff --git a/include/afio/v2.0/detail/impl/posix/file_handle.ipp b/include/afio/v2.0/detail/impl/posix/file_handle.ipp index 7ad66d1f..a65eabff 100644 --- a/include/afio/v2.0/detail/impl/posix/file_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/file_handle.ipp @@ -48,14 +48,6 @@ result<file_handle> file_handle::file(const path_handle &base, file_handle::path { return {errno, std::system_category()}; } - if(!(flags & flag::disable_safety_unlinks)) - { - if(!ret.value()._fetch_inode()) - { - // If fetching inode failed e.g. were opening device, disable safety unlinks - ret.value()._flags &= ~flag::disable_safety_unlinks; - } - } if((flags & flag::disable_prefetching) || (flags & flag::maximum_prefetching)) { #ifdef POSIX_FADV_SEQUENTIAL @@ -98,7 +90,6 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode, if(-1 != nativeh.fd) { ret.value()._flags |= flag::anonymous_inode; - OUTCOME_TRYV(ret.value()._fetch_inode()); // It can be useful to know the inode of temporary inodes ret.value()._flags &= ~flag::unlink_on_close; // It's already unlinked return ret; } @@ -132,7 +123,6 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode, { return {errno, std::system_category()}; } - OUTCOME_TRYV(ret.value()._fetch_inode()); // It can be useful to know the inode of temporary inodes ret.value()._flags &= ~flag::unlink_on_close; return ret; } diff --git a/include/afio/v2.0/detail/impl/posix/fs_handle.ipp b/include/afio/v2.0/detail/impl/posix/fs_handle.ipp index d521ce07..0856b5ea 100644 --- a/include/afio/v2.0/detail/impl/posix/fs_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/fs_handle.ipp @@ -31,7 +31,7 @@ Distributed under the Boost Software License, Version 1.0. AFIO_V2_NAMESPACE_BEGIN -result<void> fs_handle::_fetch_inode() noexcept +result<void> fs_handle::_fetch_inode() const noexcept { stat_t s(nullptr); OUTCOME_TRYV(s.fill(_get_handle(), stat_t::want::dev | stat_t::want::ino)); @@ -145,6 +145,10 @@ result<path_handle> fs_handle::parent_path_handle(deadline d) const noexcept { AFIO_LOG_FUNCTION_CALL(this); auto &h = _get_handle(); + if(_devid == 0 && _inode == 0) + { + OUTCOME_TRY(_fetch_inode()); + } return containing_directory({}, h, *this, d); } @@ -165,7 +169,7 @@ result<void> fs_handle::relink(const path_handle &base, path_view_type path, boo snprintf(_path, PATH_MAX, "/proc/self/fd/%d", h.native_handle().fd); if(-1 == ::linkat(AT_FDCWD, _path, base.is_valid() ? base.native_handle().fd : AT_FDCWD, zpath.buffer, AT_SYMLINK_FOLLOW)) { - return { errno, std::system_category() }; + return {errno, std::system_category()}; } h._flags &= ~handle::flag::anonymous_inode; return success(); @@ -173,6 +177,10 @@ result<void> fs_handle::relink(const path_handle &base, path_view_type path, boo #endif // Open our containing directory filesystem::path filename; + if(_devid == 0 && _inode == 0) + { + OUTCOME_TRY(_fetch_inode()); + } OUTCOME_TRY(dirh, containing_directory(std::ref(filename), h, *this, d)); if(!atomic_replace) { @@ -186,12 +194,12 @@ result<void> fs_handle::relink(const path_handle &base, path_view_type path, boo // Otherwise we need to use linkat followed by renameat (non-atomic) if(-1 == ::linkat(dirh.native_handle().fd, filename.c_str(), base.is_valid() ? base.native_handle().fd : AT_FDCWD, zpath.buffer, 0)) { - return { errno, std::system_category() }; + return {errno, std::system_category()}; } } if(-1 == ::renameat(dirh.native_handle().fd, filename.c_str(), base.is_valid() ? base.native_handle().fd : AT_FDCWD, zpath.buffer)) { - return { errno, std::system_category() }; + return {errno, std::system_category()}; } return success(); } @@ -202,6 +210,10 @@ result<void> fs_handle::unlink(deadline d) noexcept auto &h = _get_handle(); // Open our containing directory filesystem::path filename; + if(_devid == 0 && _inode == 0) + { + OUTCOME_TRY(_fetch_inode()); + } OUTCOME_TRY(dirh, containing_directory(std::ref(filename), h, *this, d)); if(-1 == ::unlinkat(dirh.native_handle().fd, filename.c_str(), h.is_directory() ? AT_REMOVEDIR : 0)) { diff --git a/include/afio/v2.0/detail/impl/windows/directory_handle.ipp b/include/afio/v2.0/detail/impl/windows/directory_handle.ipp index 1c2e2e2f..a60f9e0a 100644 --- a/include/afio/v2.0/detail/impl/windows/directory_handle.ipp +++ b/include/afio/v2.0/detail/impl/windows/directory_handle.ipp @@ -132,14 +132,6 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa return {static_cast<int>(errcode), std::system_category()}; } } - if(!(flags & flag::disable_safety_unlinks)) - { - if(!ret.value()._fetch_inode()) - { - // If fetching inode failed e.g. were opening device, disable safety unlinks - ret.value()._flags &= ~flag::disable_safety_unlinks; - } - } return ret; } diff --git a/include/afio/v2.0/detail/impl/windows/file_handle.ipp b/include/afio/v2.0/detail/impl/windows/file_handle.ipp index 4b9fbd19..a80ddad7 100644 --- a/include/afio/v2.0/detail/impl/windows/file_handle.ipp +++ b/include/afio/v2.0/detail/impl/windows/file_handle.ipp @@ -149,14 +149,6 @@ result<file_handle> file_handle::file(const path_handle &base, file_handle::path break; } } - if(!(flags & flag::disable_safety_unlinks)) - { - if(!ret.value()._fetch_inode()) - { - // If fetching inode failed e.g. were opening device, disable safety unlinks - ret.value()._flags &= ~flag::disable_safety_unlinks; - } - } if(need_to_set_sparse && !(flags & flag::win_disable_sparse_file_creation)) { DWORD bytesout = 0; @@ -251,7 +243,6 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode, } } // std::cerr << random << std::endl; - OUTCOME_TRYV(ret.value()._fetch_inode()); // It can be useful to know the inode of temporary inodes if(nativeh.h != nullptr) { // Hide this item diff --git a/include/afio/v2.0/detail/impl/windows/fs_handle.ipp b/include/afio/v2.0/detail/impl/windows/fs_handle.ipp index fc1fdaba..29ce00da 100644 --- a/include/afio/v2.0/detail/impl/windows/fs_handle.ipp +++ b/include/afio/v2.0/detail/impl/windows/fs_handle.ipp @@ -29,7 +29,7 @@ Distributed under the Boost Software License, Version 1.0. AFIO_V2_NAMESPACE_BEGIN -result<void> fs_handle::_fetch_inode() noexcept +result<void> fs_handle::_fetch_inode() const noexcept { stat_t s; OUTCOME_TRYV(s.fill(_get_handle(), stat_t::want::dev | stat_t::want::ino)); @@ -45,6 +45,10 @@ result<path_handle> fs_handle::parent_path_handle(deadline d) const noexcept AFIO_LOG_FUNCTION_CALL(this); auto &h = _get_handle(); AFIO_WIN_DEADLINE_TO_SLEEP_INIT(d); + if(_devid == 0 && _inode == 0) + { + OUTCOME_TRY(_fetch_inode()); + } try { for(;;) diff --git a/include/afio/v2.0/fs_handle.hpp b/include/afio/v2.0/fs_handle.hpp index a9659647..45e1a7c7 100644 --- a/include/afio/v2.0/fs_handle.hpp +++ b/include/afio/v2.0/fs_handle.hpp @@ -55,11 +55,11 @@ public: using unique_id_type = QUICKCPPLIB_NAMESPACE::integers128::uint128; protected: - dev_t _devid{0}; - ino_t _inode{0}; + mutable dev_t _devid{0}; + mutable ino_t _inode{0}; //! Fill in _devid and _inode from the handle via fstat() - AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<void> _fetch_inode() noexcept; + AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<void> _fetch_inode() const noexcept; virtual const handle &_get_handle() const noexcept = 0; @@ -96,12 +96,30 @@ public: fs_handle &operator=(const fs_handle &o) = delete; //! Unless `flag::disable_safety_unlinks` is set, the device id of the file when opened - dev_t st_dev() const noexcept { return _devid; } + dev_t st_dev() const noexcept + { + if(_devid == 0 && _inode == 0) + { + (void) _fetch_inode(); + } + return _devid; + } //! Unless `flag::disable_safety_unlinks` is set, the inode of the file when opened. When combined with st_dev(), forms a unique identifer on this system - ino_t st_ino() const noexcept { return _inode; } + ino_t st_ino() const noexcept + { + if(_devid == 0 && _inode == 0) + { + (void) _fetch_inode(); + } + return _inode; + } //! A unique identifier for this handle across the entire system. Can be used in hash tables etc. unique_id_type unique_id() const noexcept { + if(_devid == 0 && _inode == 0) + { + (void) _fetch_inode(); + } unique_id_type ret; ret.as_longlongs[0] = _devid; ret.as_longlongs[1] = _inode; |