0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::fs: Handle partial reads internally with 'all' option.

This commit is contained in:
Jason Volk 2018-12-18 13:41:45 -08:00
parent c3cf4c02dd
commit bb3a68a95e
2 changed files with 42 additions and 4 deletions

View file

@ -51,6 +51,12 @@ struct ircd::fs::read_opts
/// available or not enabled, or doesn't support this operation, setting /// available or not enabled, or doesn't support this operation, setting
/// this has no effect. /// this has no effect.
bool aio {true}; 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 inline

View file

@ -564,6 +564,11 @@ ircd::fs::flush(const fd &fd,
// fs/read.h // fs/read.h
// //
namespace ircd::fs
{
static size_t read(const fd &, const const_iovec_view &, const read_opts &);
}
ircd::fs::read_opts ircd::fs::read_opts
const ircd::fs::read_opts_default const ircd::fs::read_opts_default
{}; {};
@ -670,15 +675,42 @@ ircd::fs::read(const string_view &path,
size_t size_t
ircd::fs::read(const fd &fd, ircd::fs::read(const fd &fd,
const mutable_buffers &bufs, 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) const read_opts &opts)
{ {
#ifdef IRCD_USE_AIO #ifdef IRCD_USE_AIO
if(likely(aio::context) && opts.aio) if(aio::context && opts.aio)
return aio::read(fd, bufs, opts); return aio::read(fd, iov, opts);
#endif #endif
const auto iov(make_iov(bufs)); return syscall(::preadv, fd, iov.data(), iov.size(), opts.offset);
return size_t(syscall(::preadv, fd, iov.data(), iov.size(), opts.offset));
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////