mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 07:23:53 +01:00
ircd::fs: Handle partial reads internally with 'all' option.
This commit is contained in:
parent
c3cf4c02dd
commit
bb3a68a95e
2 changed files with 42 additions and 4 deletions
|
@ -51,6 +51,12 @@ struct ircd::fs::read_opts
|
|||
/// available or not enabled, or doesn't support this operation, setting
|
||||
/// this has no effect.
|
||||
bool aio {true};
|
||||
|
||||
/// Yields the ircd::ctx until the buffers are full or EOF. This performs
|
||||
/// the unix incremental read loop internally. When this option is true,
|
||||
/// any return value from a function in the read suite will not be a
|
||||
/// partial value requiring another invocation of read.
|
||||
bool all {true};
|
||||
};
|
||||
|
||||
inline
|
||||
|
|
40
ircd/fs.cc
40
ircd/fs.cc
|
@ -564,6 +564,11 @@ ircd::fs::flush(const fd &fd,
|
|||
// fs/read.h
|
||||
//
|
||||
|
||||
namespace ircd::fs
|
||||
{
|
||||
static size_t read(const fd &, const const_iovec_view &, const read_opts &);
|
||||
}
|
||||
|
||||
ircd::fs::read_opts
|
||||
const ircd::fs::read_opts_default
|
||||
{};
|
||||
|
@ -670,15 +675,42 @@ ircd::fs::read(const string_view &path,
|
|||
size_t
|
||||
ircd::fs::read(const fd &fd,
|
||||
const mutable_buffers &bufs,
|
||||
const read_opts &opts_)
|
||||
{
|
||||
size_t ret(0);
|
||||
read_opts opts(opts_); do
|
||||
{
|
||||
assert(opts.offset >= opts_.offset);
|
||||
const size_t off(opts.offset - opts_.offset);
|
||||
assert(off <= buffers::size(bufs));
|
||||
assert(ret <= buffers::size(bufs));
|
||||
const auto iov(make_iov(bufs, ret));
|
||||
ret += read(fd, iov, opts);
|
||||
if(!opts_.all)
|
||||
break;
|
||||
|
||||
if(off >= ret)
|
||||
break;
|
||||
|
||||
opts.offset = opts_.offset + ret;
|
||||
}
|
||||
while(ret < buffers::size(bufs));
|
||||
assert(opts.offset >= opts_.offset);
|
||||
assert(ret <= buffers::size(bufs));
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::fs::read(const fd &fd,
|
||||
const const_iovec_view &iov,
|
||||
const read_opts &opts)
|
||||
{
|
||||
#ifdef IRCD_USE_AIO
|
||||
if(likely(aio::context) && opts.aio)
|
||||
return aio::read(fd, bufs, opts);
|
||||
if(aio::context && opts.aio)
|
||||
return aio::read(fd, iov, opts);
|
||||
#endif
|
||||
|
||||
const auto iov(make_iov(bufs));
|
||||
return size_t(syscall(::preadv, fd, iov.data(), iov.size(), opts.offset));
|
||||
return syscall(::preadv, fd, iov.data(), iov.size(), opts.offset);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue