diff --git a/include/ircd/fs/iov.h b/include/ircd/fs/iov.h index f1bbf3491..df98209d2 100644 --- a/include/ircd/fs/iov.h +++ b/include/ircd/fs/iov.h @@ -18,17 +18,23 @@ extern "C" namespace ircd::fs { + using const_iovec_view = vector_view; + using iovec_view = vector_view; using const_buffers = vector_view; using mutable_buffers = vector_view; // utility; count the total bytes of an iov. - size_t bytes(const vector_view &); + size_t bytes(const const_iovec_view &); + + // Transforms our buffers to struct iovec ones. + const_iovec_view make_iov(const iovec_view &, const const_buffers &); + const_iovec_view make_iov(const iovec_view &, const mutable_buffers &); // Transforms our buffers to struct iovec ones. This is done using an // internal thread_local array of IOV_MAX. The returned view is of that // array. We get away with using a single buffer because the synchronous // readv()/writev() calls block the thread and for AIO the iov is copied out // of userspace on io_submit(). - vector_view make_iov(const const_buffers &); - vector_view make_iov(const mutable_buffers &); + const_iovec_view make_iov(const const_buffers &); + const_iovec_view make_iov(const mutable_buffers &); } diff --git a/ircd/aio.cc b/ircd/aio.cc index 7c18340ac..206d254a7 100644 --- a/ircd/aio.cc +++ b/ircd/aio.cc @@ -84,7 +84,7 @@ ircd::fs::aio::fdsync(const fd &fd, // ircd::fs::aio::request::read::read(const int &fd, - const vector_view &iov, + const const_iovec_view &iov, const read_opts &opts) :request{fd} { @@ -129,7 +129,7 @@ ircd::fs::aio::read(const fd &fd, // ircd::fs::aio::request::write::write(const int &fd, - const vector_view &iov, + const const_iovec_view &iov, const write_opts &opts) :request{fd} { @@ -548,7 +548,7 @@ catch(const ctx::terminated &) throw; } -ircd::vector_view +ircd::fs::const_iovec_view ircd::fs::aio::request::iovec() const { diff --git a/ircd/aio.h b/ircd/aio.h index 4821cb1f4..1966ad486 100644 --- a/ircd/aio.h +++ b/ircd/aio.h @@ -17,8 +17,8 @@ namespace ircd::fs::aio struct request; void prefetch(const fd &, const size_t &, const read_opts &); - size_t write(const fd &, const vector_view &, const write_opts &); - size_t read(const fd &, const vector_view &, const read_opts &); + size_t write(const fd &, const const_buffers &, const write_opts &); + size_t read(const fd &, const mutable_buffers &, const read_opts &); void fdsync(const fd &, const fsync_opts &); void fsync(const fd &, const fsync_opts &); } @@ -74,7 +74,7 @@ struct ircd::fs::aio::request ssize_t errcode {0}; public: - vector_view iovec() const; + const_iovec_view iovec() const; size_t operator()(); void cancel(); @@ -87,14 +87,14 @@ struct ircd::fs::aio::request struct ircd::fs::aio::request::read :request { - read(const int &fd, const vector_view &, const read_opts &); + read(const int &fd, const const_iovec_view &, const read_opts &); }; /// Write request control block struct ircd::fs::aio::request::write :request { - write(const int &fd, const vector_view &, const write_opts &); + write(const int &fd, const const_iovec_view &, const write_opts &); }; /// fdsync request control block diff --git a/ircd/fs.cc b/ircd/fs.cc index 0aabda08e..a571d3329 100644 --- a/ircd/fs.cc +++ b/ircd/fs.cc @@ -1138,58 +1138,72 @@ namespace ircd::fs thread_local std::array _iov_; } -ircd::vector_view +ircd::fs::const_iovec_view ircd::fs::make_iov(const mutable_buffers &bufs) { - if(unlikely(bufs.size() > IOV_MAX)) + if(unlikely(bufs.size() > _iov_.size())) throw error { make_error_code(std::errc::invalid_argument), - "Buffer count of %zu excheeds IOV_MAX of %zu", + "Buffer count of %zu exceeds IOV_MAX of %zu", bufs.size(), - IOV_MAX + _iov_.size() }; + return make_iov(iovec_view(_iov_.data(), _iov_.size()), bufs); +} + +ircd::fs::const_iovec_view +ircd::fs::make_iov(const const_buffers &bufs) +{ + if(unlikely(bufs.size() > _iov_.size())) + throw error + { + make_error_code(std::errc::invalid_argument), + "Buffer count of %zu exceeds IOV_MAX of %zu", + bufs.size(), + _iov_.size() + }; + + return make_iov(iovec_view(_iov_.data(), _iov_.size()), bufs); +} + +ircd::fs::const_iovec_view +ircd::fs::make_iov(const iovec_view &iov, + const mutable_buffers &bufs) +{ size_t i(0); - for(; i < bufs.size(); ++i) + for(; i < bufs.size() && i < iov.size(); ++i) _iov_.at(i) = { buffer::data(bufs[i]), buffer::size(bufs[i]) }; - return + return const_iovec_view { - _iov_.data(), i + iov.data(), i }; } -ircd::vector_view -ircd::fs::make_iov(const const_buffers &bufs) +ircd::fs::const_iovec_view +ircd::fs::make_iov(const iovec_view &iov, + const const_buffers &bufs) { - if(unlikely(bufs.size() > IOV_MAX)) - throw error - { - make_error_code(std::errc::invalid_argument), - "Buffer count of %zu excheeds IOV_MAX of %zu", - bufs.size(), - IOV_MAX - }; - size_t i(0); - for(; i < bufs.size(); ++i) - _iov_.at(i) = + for(; i < bufs.size() && i < iov.size(); ++i) + iov.at(i) = { const_cast(buffer::data(bufs[i])), buffer::size(bufs[i]) }; - return + return const_iovec_view { - _iov_.data(), i + iov.data(), i }; } size_t -ircd::fs::bytes(const vector_view &iov) +ircd::fs::bytes(const const_iovec_view &iov) { return std::accumulate(begin(iov), end(iov), size_t(0), [] (auto ret, const auto &iov)