mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 00:14:07 +01:00
ircd::fs: Propagate EAGAIN without exception for !opts.blocking operations.
This commit is contained in:
parent
fbcd38fa17
commit
900fab1e79
2 changed files with 71 additions and 22 deletions
82
ircd/fs.cc
82
ircd/fs.cc
|
@ -702,14 +702,23 @@ ircd::fs::_read(const fd &fd,
|
||||||
flags(opts)
|
flags(opts)
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto ret
|
ssize_t ret; do
|
||||||
{
|
{
|
||||||
opts.interruptible?
|
ret = ::preadv2(int(fd), iov.data(), iov.size(), opts.offset, flags_);
|
||||||
syscall(::preadv2, fd, iov.data(), iov.size(), opts.offset, flags_):
|
}
|
||||||
syscall_nointr(::preadv2, fd, iov.data(), iov.size(), opts.offset, flags_)
|
while(!opts.interruptible && unlikely(ret == -1 && errno == EINTR));
|
||||||
|
|
||||||
|
static_assert(EAGAIN == EWOULDBLOCK);
|
||||||
|
if(!opts.blocking && ret == -1 && errno == EAGAIN)
|
||||||
|
return 0UL;
|
||||||
|
|
||||||
|
if(unlikely(ret == -1))
|
||||||
|
throw std::system_error
|
||||||
|
{
|
||||||
|
errno, std::system_category()
|
||||||
};
|
};
|
||||||
|
|
||||||
return size_t(ret);
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
size_t
|
size_t
|
||||||
|
@ -717,14 +726,23 @@ ircd::fs::_read(const fd &fd,
|
||||||
const const_iovec_view &iov,
|
const const_iovec_view &iov,
|
||||||
const read_opts &opts)
|
const read_opts &opts)
|
||||||
{
|
{
|
||||||
const auto ret
|
ssize_t ret; do
|
||||||
{
|
{
|
||||||
opts.interruptible?
|
ret = ::preadv(int(fd), iov.data(), iov.size(), opts.offset);
|
||||||
syscall(::preadv, fd, iov.data(), iov.size(), opts.offset):
|
}
|
||||||
syscall_nointr(::preadv, fd, iov.data(), iov.size(), opts.offset)
|
while(!opts.interruptible && unlikely(ret == -1 && errno == EINTR));
|
||||||
|
|
||||||
|
static_assert(EAGAIN == EWOULDBLOCK);
|
||||||
|
if(unlikely(!opts.blocking && ret == -1 && errno == EAGAIN))
|
||||||
|
return 0UL;
|
||||||
|
|
||||||
|
if(unlikely(ret == -1))
|
||||||
|
throw std::system_error
|
||||||
|
{
|
||||||
|
errno, std::system_category()
|
||||||
};
|
};
|
||||||
|
|
||||||
return size_t(ret);
|
return ret;
|
||||||
}
|
}
|
||||||
#endif // HAVE_PREADV2
|
#endif // HAVE_PREADV2
|
||||||
|
|
||||||
|
@ -1050,7 +1068,7 @@ ircd::fs::write(const fd &fd,
|
||||||
while(opts.all && opts_.offset >= 0 && off < buffers::size(bufs));
|
while(opts.all && opts_.offset >= 0 && off < buffers::size(bufs));
|
||||||
assert(opts.offset >= opts_.offset);
|
assert(opts.offset >= opts_.offset);
|
||||||
assert(ssize_t(off) == opts.offset - opts_.offset);
|
assert(ssize_t(off) == opts.offset - opts_.offset);
|
||||||
assert(!opts.all || off == buffers::size(bufs));
|
assert(!opts.all || !opts.blocking || off == buffers::size(bufs));
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
@ -1099,10 +1117,23 @@ ircd::fs::_write__pwritev1(const fd &fd,
|
||||||
const const_iovec_view &iov,
|
const const_iovec_view &iov,
|
||||||
const write_opts &opts)
|
const write_opts &opts)
|
||||||
{
|
{
|
||||||
return
|
ssize_t ret; do
|
||||||
opts.interruptible?
|
{
|
||||||
syscall(::pwritev, fd, iov.data(), iov.size(), opts.offset):
|
ret = ::pwritev(int(fd), iov.data(), iov.size(), opts.offset);
|
||||||
syscall_nointr(::pwritev, fd, iov.data(), iov.size(), opts.offset);
|
}
|
||||||
|
while(!opts.interruptible && unlikely(ret == -1 && errno == EINTR));
|
||||||
|
|
||||||
|
static_assert(EAGAIN == EWOULDBLOCK);
|
||||||
|
if(unlikely(!opts.blocking && ret == -1 && errno == EAGAIN))
|
||||||
|
return 0UL;
|
||||||
|
|
||||||
|
if(unlikely(ret == -1))
|
||||||
|
throw std::system_error
|
||||||
|
{
|
||||||
|
errno, std::system_category()
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PWRITEV2
|
#ifdef HAVE_PWRITEV2
|
||||||
|
@ -1124,10 +1155,23 @@ ircd::fs::_write__pwritev2(const fd &fd,
|
||||||
flags(opts)
|
flags(opts)
|
||||||
};
|
};
|
||||||
|
|
||||||
return
|
ssize_t ret; do
|
||||||
opts.interruptible?
|
{
|
||||||
syscall(::pwritev2, fd, iov.data(), iov.size(), offset, flags_):
|
ret = ::pwritev2(int(fd), iov.data(), iov.size(), opts.offset, flags_);
|
||||||
syscall_nointr(::pwritev2, fd, iov.data(), iov.size(), offset, flags_);
|
}
|
||||||
|
while(!opts.interruptible && unlikely(ret == -1 && errno == EINTR));
|
||||||
|
|
||||||
|
static_assert(EAGAIN == EWOULDBLOCK);
|
||||||
|
if(!opts.blocking && ret == -1 && errno == EAGAIN)
|
||||||
|
return 0UL;
|
||||||
|
|
||||||
|
if(unlikely(ret == -1))
|
||||||
|
throw std::system_error
|
||||||
|
{
|
||||||
|
errno, std::system_category()
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
size_t
|
size_t
|
||||||
|
|
|
@ -279,7 +279,7 @@ ircd::fs::aio::write(const fd &fd,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Does linux ever not complete all bytes for an AIO?
|
// Does linux ever not complete all bytes for an AIO?
|
||||||
assert(bytes == req_bytes);
|
assert(!opts.blocking || bytes == req_bytes);
|
||||||
|
|
||||||
stats.bytes_write += bytes;
|
stats.bytes_write += bytes;
|
||||||
stats.writes++;
|
stats.writes++;
|
||||||
|
@ -411,6 +411,11 @@ ircd::fs::aio::request::operator()()
|
||||||
if(likely(retval != -1))
|
if(likely(retval != -1))
|
||||||
return size_t(retval);
|
return size_t(retval);
|
||||||
|
|
||||||
|
assert(opts);
|
||||||
|
static_assert(EAGAIN == EWOULDBLOCK);
|
||||||
|
if(!opts->blocking && retval == -1 && errcode == EAGAIN)
|
||||||
|
return 0UL;
|
||||||
|
|
||||||
stats.errors++;
|
stats.errors++;
|
||||||
stats.bytes_errors += submitted_bytes;
|
stats.bytes_errors += submitted_bytes;
|
||||||
thread_local char errbuf[512]; fmt::sprintf
|
thread_local char errbuf[512]; fmt::sprintf
|
||||||
|
|
Loading…
Reference in a new issue