mirror of
https://github.com/matrix-construct/construct
synced 2024-12-27 07:54:05 +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)
|
||||
};
|
||||
|
||||
const auto ret
|
||||
ssize_t ret; do
|
||||
{
|
||||
opts.interruptible?
|
||||
syscall(::preadv2, fd, iov.data(), iov.size(), opts.offset, flags_):
|
||||
syscall_nointr(::preadv2, fd, iov.data(), iov.size(), opts.offset, flags_)
|
||||
ret = ::preadv2(int(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
|
||||
size_t
|
||||
|
@ -717,14 +726,23 @@ ircd::fs::_read(const fd &fd,
|
|||
const const_iovec_view &iov,
|
||||
const read_opts &opts)
|
||||
{
|
||||
const auto ret
|
||||
ssize_t ret; do
|
||||
{
|
||||
opts.interruptible?
|
||||
syscall(::preadv, fd, iov.data(), iov.size(), opts.offset):
|
||||
syscall_nointr(::preadv, fd, iov.data(), iov.size(), opts.offset)
|
||||
ret = ::preadv(int(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
|
||||
|
||||
|
@ -1050,7 +1068,7 @@ ircd::fs::write(const fd &fd,
|
|||
while(opts.all && opts_.offset >= 0 && off < buffers::size(bufs));
|
||||
assert(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;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
@ -1099,10 +1117,23 @@ ircd::fs::_write__pwritev1(const fd &fd,
|
|||
const const_iovec_view &iov,
|
||||
const write_opts &opts)
|
||||
{
|
||||
return
|
||||
opts.interruptible?
|
||||
syscall(::pwritev, fd, iov.data(), iov.size(), opts.offset):
|
||||
syscall_nointr(::pwritev, fd, iov.data(), iov.size(), opts.offset);
|
||||
ssize_t ret; do
|
||||
{
|
||||
ret = ::pwritev(int(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
|
||||
|
@ -1124,10 +1155,23 @@ ircd::fs::_write__pwritev2(const fd &fd,
|
|||
flags(opts)
|
||||
};
|
||||
|
||||
return
|
||||
opts.interruptible?
|
||||
syscall(::pwritev2, fd, iov.data(), iov.size(), offset, flags_):
|
||||
syscall_nointr(::pwritev2, fd, iov.data(), iov.size(), offset, flags_);
|
||||
ssize_t ret; do
|
||||
{
|
||||
ret = ::pwritev2(int(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 ret;
|
||||
}
|
||||
#else
|
||||
size_t
|
||||
|
|
|
@ -279,7 +279,7 @@ ircd::fs::aio::write(const fd &fd,
|
|||
};
|
||||
|
||||
// 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.writes++;
|
||||
|
@ -411,6 +411,11 @@ ircd::fs::aio::request::operator()()
|
|||
if(likely(retval != -1))
|
||||
return size_t(retval);
|
||||
|
||||
assert(opts);
|
||||
static_assert(EAGAIN == EWOULDBLOCK);
|
||||
if(!opts->blocking && retval == -1 && errcode == EAGAIN)
|
||||
return 0UL;
|
||||
|
||||
stats.errors++;
|
||||
stats.bytes_errors += submitted_bytes;
|
||||
thread_local char errbuf[512]; fmt::sprintf
|
||||
|
|
Loading…
Reference in a new issue