mirror of
https://github.com/matrix-construct/construct
synced 2024-11-26 00:32:35 +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
136
ircd/fs.cc
136
ircd/fs.cc
|
@ -1000,56 +1000,23 @@ ircd::fs::append(const string_view &path,
|
|||
return append(fd, bufs, opts);
|
||||
}
|
||||
|
||||
// Platform-specific append() implementations.
|
||||
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();
|
||||
}
|
||||
|
||||
#if defined(HAVE_PWRITEV2) && defined(RWF_APPEND)
|
||||
size_t
|
||||
ircd::fs::append(const fd &fd,
|
||||
const const_buffers &bufs,
|
||||
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_);
|
||||
opts.offset = -1;
|
||||
return write(fd, bufs, opts);
|
||||
}
|
||||
|
||||
#else
|
||||
/// When we don't have pwritev2() we have to eat the cost of an
|
||||
/// extra lseek() to the end of the file.
|
||||
size_t
|
||||
ircd::fs::_append__no_rwf(const fd &fd,
|
||||
const const_buffers &bufs,
|
||||
const write_opts &opts_)
|
||||
ircd::fs::append(const fd &fd,
|
||||
const const_buffers &bufs,
|
||||
const write_opts &opts_)
|
||||
{
|
||||
auto opts(opts_);
|
||||
if(!opts.offset || opts.offset == -1)
|
||||
|
@ -1057,6 +1024,7 @@ ircd::fs::_append__no_rwf(const fd &fd,
|
|||
|
||||
return write(fd, bufs, opts);
|
||||
}
|
||||
#endif defined(HAVE_PWRITEV2) && defined(RWF_APPEND)
|
||||
|
||||
//
|
||||
// write
|
||||
|
@ -1107,21 +1075,10 @@ ircd::fs::write(const string_view &path,
|
|||
return write(fd, bufs, opts);
|
||||
}
|
||||
|
||||
// Platform-specific write() implementations.
|
||||
namespace ircd::fs
|
||||
{
|
||||
static int flags(const write_opts &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,58 +1144,16 @@ ircd::fs::write(const fd &fd,
|
|||
#ifdef IRCD_USE_AIO
|
||||
if(likely(aio::system) && opts.aio)
|
||||
return aio::write(fd, iov, opts);
|
||||
#endif
|
||||
#endif IRCD_USE_AIO
|
||||
|
||||
return _write_pwritev(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;
|
||||
return _write(fd, iov, opts);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PWRITEV2
|
||||
size_t
|
||||
ircd::fs::_write__pwritev2(const fd &fd,
|
||||
const const_iovec_view &iov,
|
||||
const write_opts &opts)
|
||||
ircd::fs::_write(const fd &fd,
|
||||
const const_iovec_view &iov,
|
||||
const write_opts &opts)
|
||||
{
|
||||
// Manpages sez that when appending with RWF_APPEND, the offset has no
|
||||
// effect on the write; but if the value of the offset is -1 then the
|
||||
|
@ -1273,16 +1188,27 @@ ircd::fs::_write__pwritev2(const fd &fd,
|
|||
}
|
||||
#else
|
||||
size_t
|
||||
[[noreturn]]
|
||||
ircd::fs::_write__pwritev2(const fd &fd,
|
||||
const const_iovec_view &iov,
|
||||
const write_opts &opts)
|
||||
ircd::fs::_write(const fd &fd,
|
||||
const const_iovec_view &iov,
|
||||
const write_opts &opts)
|
||||
{
|
||||
ircd::terminate(panic
|
||||
ssize_t ret; do
|
||||
{
|
||||
"This build does not support pwritev2()."
|
||||
" This function should not have been selected."
|
||||
});
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue