mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 18:22:50 +01:00
ircd::fs: Eliminate uses of GNU ifunc.
This commit is contained in:
parent
129676d06e
commit
0575f9c500
1 changed files with 31 additions and 105 deletions
124
ircd/fs.cc
124
ircd/fs.cc
|
@ -1000,54 +1000,21 @@ ircd::fs::append(const string_view &path,
|
||||||
return append(fd, bufs, opts);
|
return append(fd, bufs, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform-specific append() implementations.
|
#if defined(HAVE_PWRITEV2) && defined(RWF_APPEND)
|
||||||
namespace ircd::fs
|
|
||||||
{
|
|
||||||
static size_t _append__rwf(const fd &, const const_buffers &, const write_opts &);
|
|
||||||
static size_t _append__no_rwf(const fd &, const const_buffers &, const write_opts &);
|
|
||||||
extern "C" decltype(_append__rwf) *ircd_fs_append__resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ircd::fs::append(const fd &fd,
|
ircd::fs::append(const fd &fd,
|
||||||
const const_buffers &bufs,
|
const const_buffers &bufs,
|
||||||
const write_opts &opts_)
|
const write_opts &opts_)
|
||||||
__attribute__((ifunc("ircd_fs_append__resolve")));
|
|
||||||
|
|
||||||
/// This function allows the linker to dynamically resolve the append() definition
|
|
||||||
/// we'll be using during this execution. We check for fs::support_append which was
|
|
||||||
/// initialized based on the kernel version.
|
|
||||||
extern "C" decltype(ircd::fs::_append__rwf) *
|
|
||||||
ircd::fs::ircd_fs_append__resolve()
|
|
||||||
{
|
|
||||||
log::logf
|
|
||||||
{
|
|
||||||
log, support_append? log::DEBUG : log::DWARNING,
|
|
||||||
"This host '%s %s' %s the RWF_APPEND flag to pwritev2(2).",
|
|
||||||
info::kernel_name,
|
|
||||||
string_view{info::kernel_version},
|
|
||||||
support_append? "supports"_sv : "does not support"_sv,
|
|
||||||
};
|
|
||||||
|
|
||||||
return support_append? _append__rwf : _append__no_rwf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// When we have RWF_APPEND. We unconditionally set the offset to the
|
|
||||||
/// value -1.
|
|
||||||
size_t
|
|
||||||
ircd::fs::_append__rwf(const fd &fd,
|
|
||||||
const const_buffers &bufs,
|
|
||||||
const write_opts &opts_)
|
|
||||||
{
|
{
|
||||||
auto opts(opts_);
|
auto opts(opts_);
|
||||||
opts.offset = -1;
|
opts.offset = -1;
|
||||||
return write(fd, bufs, opts);
|
return write(fd, bufs, opts);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
/// When we don't have pwritev2() we have to eat the cost of an
|
/// When we don't have pwritev2() we have to eat the cost of an
|
||||||
/// extra lseek() to the end of the file.
|
/// extra lseek() to the end of the file.
|
||||||
size_t
|
size_t
|
||||||
ircd::fs::_append__no_rwf(const fd &fd,
|
ircd::fs::append(const fd &fd,
|
||||||
const const_buffers &bufs,
|
const const_buffers &bufs,
|
||||||
const write_opts &opts_)
|
const write_opts &opts_)
|
||||||
{
|
{
|
||||||
|
@ -1057,6 +1024,7 @@ ircd::fs::_append__no_rwf(const fd &fd,
|
||||||
|
|
||||||
return write(fd, bufs, opts);
|
return write(fd, bufs, opts);
|
||||||
}
|
}
|
||||||
|
#endif defined(HAVE_PWRITEV2) && defined(RWF_APPEND)
|
||||||
|
|
||||||
//
|
//
|
||||||
// write
|
// write
|
||||||
|
@ -1107,21 +1075,10 @@ ircd::fs::write(const string_view &path,
|
||||||
return write(fd, bufs, opts);
|
return write(fd, bufs, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform-specific write() implementations.
|
|
||||||
namespace ircd::fs
|
namespace ircd::fs
|
||||||
{
|
{
|
||||||
static int flags(const write_opts &opts);
|
static int flags(const write_opts &opts);
|
||||||
|
static size_t _write(const fd &, const const_iovec_view &, const write_opts &);
|
||||||
static size_t _write__pwritev2(const fd &, const const_iovec_view &, const write_opts &);
|
|
||||||
static size_t _write__pwritev1(const fd &, const const_iovec_view &, const write_opts &);
|
|
||||||
extern "C" decltype(_write__pwritev1) *ircd_fs_write_pwritev__resolve();
|
|
||||||
|
|
||||||
extern size_t
|
|
||||||
_write_pwritev(const fd &,
|
|
||||||
const const_iovec_view &,
|
|
||||||
const write_opts &)
|
|
||||||
__attribute__((ifunc("ircd_fs_write_pwritev__resolve")));
|
|
||||||
|
|
||||||
static size_t write(const fd &, const const_iovec_view &, const write_opts &);
|
static size_t write(const fd &, const const_iovec_view &, const write_opts &);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1187,56 +1144,14 @@ ircd::fs::write(const fd &fd,
|
||||||
#ifdef IRCD_USE_AIO
|
#ifdef IRCD_USE_AIO
|
||||||
if(likely(aio::system) && opts.aio)
|
if(likely(aio::system) && opts.aio)
|
||||||
return aio::write(fd, iov, opts);
|
return aio::write(fd, iov, opts);
|
||||||
#endif
|
#endif IRCD_USE_AIO
|
||||||
|
|
||||||
return _write_pwritev(fd, iov, opts);
|
return _write(fd, iov, opts);
|
||||||
}
|
|
||||||
|
|
||||||
/// This function allows the linker to dynamically resolve the internal _write()
|
|
||||||
/// definition we'll be using during this execution. We check for the pwritev2
|
|
||||||
/// support flag which was initialized based on the kernel version.
|
|
||||||
extern "C" decltype(ircd::fs::_write__pwritev1) *
|
|
||||||
ircd::fs::ircd_fs_write_pwritev__resolve()
|
|
||||||
{
|
|
||||||
log::logf
|
|
||||||
{
|
|
||||||
log, support_pwritev2? log::DEBUG : log::DWARNING,
|
|
||||||
"This host '%s %s' %s the pwritev2(2) system call.",
|
|
||||||
info::kernel_name,
|
|
||||||
string_view{info::kernel_version},
|
|
||||||
support_pwritev2? "supports"_sv : "does not support"_sv
|
|
||||||
};
|
|
||||||
|
|
||||||
return support_pwritev2? _write__pwritev2 : _write__pwritev1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
ircd::fs::_write__pwritev1(const fd &fd,
|
|
||||||
const const_iovec_view &iov,
|
|
||||||
const write_opts &opts)
|
|
||||||
{
|
|
||||||
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
|
#ifdef HAVE_PWRITEV2
|
||||||
size_t
|
size_t
|
||||||
ircd::fs::_write__pwritev2(const fd &fd,
|
ircd::fs::_write(const fd &fd,
|
||||||
const const_iovec_view &iov,
|
const const_iovec_view &iov,
|
||||||
const write_opts &opts)
|
const write_opts &opts)
|
||||||
{
|
{
|
||||||
|
@ -1273,16 +1188,27 @@ ircd::fs::_write__pwritev2(const fd &fd,
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
size_t
|
size_t
|
||||||
[[noreturn]]
|
ircd::fs::_write(const fd &fd,
|
||||||
ircd::fs::_write__pwritev2(const fd &fd,
|
|
||||||
const const_iovec_view &iov,
|
const const_iovec_view &iov,
|
||||||
const write_opts &opts)
|
const write_opts &opts)
|
||||||
{
|
{
|
||||||
ircd::terminate(panic
|
ssize_t ret; do
|
||||||
{
|
{
|
||||||
"This build does not support pwritev2()."
|
ret = ::pwritev(int(fd), iov.data(), iov.size(), opts.offset);
|
||||||
" This function should not have been selected."
|
}
|
||||||
});
|
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;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue