diff options
Diffstat (limited to 'include/llfio/v2.0/detail/impl/posix')
-rw-r--r-- | include/llfio/v2.0/detail/impl/posix/file_handle.ipp | 124 | ||||
-rw-r--r-- | include/llfio/v2.0/detail/impl/posix/io_handle.ipp | 121 |
2 files changed, 124 insertions, 121 deletions
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 7a0efa72..a0f0d52d 100644 --- a/include/llfio/v2.0/detail/impl/posix/file_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/file_handle.ipp @@ -357,6 +357,130 @@ result<file_handle> file_handle::clone(mode mode_, caching caching_, deadline d) } } +#if 0 +#if !defined(__linux__) && !defined(F_OFD_SETLK) + if(0 == bytes) + { + // Non-Linux has a sane locking system in flock() if you are willing to lock the entire file + int operation = ((d && !d.nsecs) ? LOCK_NB : 0) | ((kind != file_handle::lock_kind::shared) ? LOCK_EX : LOCK_SH); + if(-1 == flock(_v.fd, operation)) + failed = true; + } + else +#endif + +#if !defined(__linux__) && !defined(F_OFD_SETLK) + if(0 == bytes) + { + if(-1 == flock(_v.fd, LOCK_UN)) + failed = true; + } + else +#endif +#endif + +result<file_handle::extent_guard> file_handle::lock_range(io_handle::extent_type offset, io_handle::extent_type bytes, file_handle::lock_kind kind, deadline d) noexcept +{ + LLFIO_LOG_FUNCTION_CALL(this); + if(d && d.nsecs > 0) + { + return errc::not_supported; + } + bool failed = false; + { + struct flock fl + { + }; + memset(&fl, 0, sizeof(fl)); + fl.l_type = (kind != file_handle::lock_kind::shared) ? F_WRLCK : F_RDLCK; + constexpr extent_type extent_topbit = static_cast<extent_type>(1) << (8 * sizeof(extent_type) - 1); + if((offset & extent_topbit) != 0u) + { + LLFIO_LOG_WARN(_v.fd, "file_handle::lock() called with offset with top bit set, masking out"); + } + if((bytes & extent_topbit) != 0u) + { + LLFIO_LOG_WARN(_v.fd, "file_handle::lock() called with bytes with top bit set, masking out"); + } + fl.l_whence = SEEK_SET; + fl.l_start = offset & ~extent_topbit; + fl.l_len = bytes & ~extent_topbit; +#ifdef F_OFD_SETLK + if(-1 == fcntl(_v.fd, (d && !d.nsecs) ? F_OFD_SETLK : F_OFD_SETLKW, &fl)) + { + if(EINVAL == errno) // OFD locks not supported on this kernel + { + if(-1 == fcntl(_v.fd, (d && !d.nsecs) ? F_SETLK : F_SETLKW, &fl)) + failed = true; + else + _flags |= flag::byte_lock_insanity; + } + else + failed = true; + } +#else + if(-1 == fcntl(_v.fd, (d && (d.nsecs == 0u)) ? F_SETLK : F_SETLKW, &fl)) + { + failed = true; + } + else + { + _flags |= flag::byte_lock_insanity; + } +#endif + } + if(failed) + { + if(d && (d.nsecs == 0u) && (EACCES == errno || EAGAIN == errno || EWOULDBLOCK == errno)) + { + return errc::timed_out; + } + return posix_error(); + } + return extent_guard(this, offset, bytes, kind); +} + +void file_handle::unlock_range(io_handle::extent_type offset, io_handle::extent_type bytes) noexcept +{ + LLFIO_LOG_FUNCTION_CALL(this); + bool failed = false; + { + struct flock fl + { + }; + memset(&fl, 0, sizeof(fl)); + fl.l_type = F_UNLCK; + constexpr extent_type extent_topbit = static_cast<extent_type>(1) << (8 * sizeof(extent_type) - 1); + fl.l_whence = SEEK_SET; + fl.l_start = offset & ~extent_topbit; + fl.l_len = bytes & ~extent_topbit; +#ifdef F_OFD_SETLK + if(-1 == fcntl(_v.fd, F_OFD_SETLK, &fl)) + { + if(EINVAL == errno) // OFD locks not supported on this kernel + { + if(-1 == fcntl(_v.fd, F_SETLK, &fl)) + failed = true; + } + else + failed = true; + } +#else + if(-1 == fcntl(_v.fd, F_SETLK, &fl)) + { + failed = true; + } +#endif + } + if(failed) + { + auto ret(posix_error()); + (void) ret; + LLFIO_LOG_FATAL(_v.fd, "io_handle::unlock() failed"); + std::terminate(); + } +} + result<file_handle::extent_type> file_handle::maximum_extent() const noexcept { LLFIO_LOG_FUNCTION_CALL(this); diff --git a/include/llfio/v2.0/detail/impl/posix/io_handle.ipp b/include/llfio/v2.0/detail/impl/posix/io_handle.ipp index 37a082b2..ddd0ba2e 100644 --- a/include/llfio/v2.0/detail/impl/posix/io_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/io_handle.ipp @@ -192,125 +192,4 @@ io_handle::io_result<io_handle::const_buffers_type> io_handle::write(io_handle:: return {reqs.buffers}; } -result<io_handle::extent_guard> io_handle::lock(io_handle::extent_type offset, io_handle::extent_type bytes, bool exclusive, deadline d) noexcept -{ - LLFIO_LOG_FUNCTION_CALL(this); - if(d && d.nsecs > 0) - { - return errc::not_supported; - } - bool failed = false; -#if !defined(__linux__) && !defined(F_OFD_SETLK) - if(0 == bytes) - { - // Non-Linux has a sane locking system in flock() if you are willing to lock the entire file - int operation = ((d && !d.nsecs) ? LOCK_NB : 0) | (exclusive ? LOCK_EX : LOCK_SH); - if(-1 == flock(_v.fd, operation)) - failed = true; - } - else -#endif - { - struct flock fl - { - }; - memset(&fl, 0, sizeof(fl)); - fl.l_type = exclusive ? F_WRLCK : F_RDLCK; - constexpr extent_type extent_topbit = static_cast<extent_type>(1) << (8 * sizeof(extent_type) - 1); - if((offset & extent_topbit) != 0u) - { - LLFIO_LOG_WARN(_v.fd, "io_handle::lock() called with offset with top bit set, masking out"); - } - if((bytes & extent_topbit) != 0u) - { - LLFIO_LOG_WARN(_v.fd, "io_handle::lock() called with bytes with top bit set, masking out"); - } - fl.l_whence = SEEK_SET; - fl.l_start = offset & ~extent_topbit; - fl.l_len = bytes & ~extent_topbit; -#ifdef F_OFD_SETLK - if(-1 == fcntl(_v.fd, (d && !d.nsecs) ? F_OFD_SETLK : F_OFD_SETLKW, &fl)) - { - if(EINVAL == errno) // OFD locks not supported on this kernel - { - if(-1 == fcntl(_v.fd, (d && !d.nsecs) ? F_SETLK : F_SETLKW, &fl)) - failed = true; - else - _flags |= flag::byte_lock_insanity; - } - else - failed = true; - } -#else - if(-1 == fcntl(_v.fd, (d && (d.nsecs == 0u)) ? F_SETLK : F_SETLKW, &fl)) - { - failed = true; - } - else - { - _flags |= flag::byte_lock_insanity; - } -#endif - } - if(failed) - { - if(d && (d.nsecs == 0u) && (EACCES == errno || EAGAIN == errno || EWOULDBLOCK == errno)) - { - return errc::timed_out; - } - return posix_error(); - } - return extent_guard(this, offset, bytes, exclusive); -} - -void io_handle::unlock(io_handle::extent_type offset, io_handle::extent_type bytes) noexcept -{ - LLFIO_LOG_FUNCTION_CALL(this); - bool failed = false; -#if !defined(__linux__) && !defined(F_OFD_SETLK) - if(0 == bytes) - { - if(-1 == flock(_v.fd, LOCK_UN)) - failed = true; - } - else -#endif - { - struct flock fl - { - }; - memset(&fl, 0, sizeof(fl)); - fl.l_type = F_UNLCK; - constexpr extent_type extent_topbit = static_cast<extent_type>(1) << (8 * sizeof(extent_type) - 1); - fl.l_whence = SEEK_SET; - fl.l_start = offset & ~extent_topbit; - fl.l_len = bytes & ~extent_topbit; -#ifdef F_OFD_SETLK - if(-1 == fcntl(_v.fd, F_OFD_SETLK, &fl)) - { - if(EINVAL == errno) // OFD locks not supported on this kernel - { - if(-1 == fcntl(_v.fd, F_SETLK, &fl)) - failed = true; - } - else - failed = true; - } -#else - if(-1 == fcntl(_v.fd, F_SETLK, &fl)) - { - failed = true; - } -#endif - } - if(failed) - { - auto ret(posix_error()); - (void) ret; - LLFIO_LOG_FATAL(_v.fd, "io_handle::unlock() failed"); - std::terminate(); - } -} - - LLFIO_V2_NAMESPACE_END |