0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 10:12:39 +01:00

ircd::fs: Reorg support section and indicators.

This commit is contained in:
Jason Volk 2020-03-20 10:04:51 -07:00
parent bc836d0fd8
commit 472ce01b50
6 changed files with 267 additions and 276 deletions

View file

@ -25,10 +25,6 @@ namespace ircd::fs::aio
struct system;
struct request;
extern const bool support;
extern const bool support_fsync;
extern const bool support_fdsync;
extern const size_t MAX_EVENTS;
extern const size_t MAX_REQPRIO;

View file

@ -36,17 +36,6 @@ namespace ircd::fs
// may make forward-declared references to boost symbols.
namespace filesystem = boost::filesystem;
// Runtime-detected support lights.
extern const bool support_pwritev2;
extern const bool support_preadv2;
extern const bool support_append;
extern const bool support_nowait;
extern const bool support_hipri;
extern const bool support_sync;
extern const bool support_dsync;
extern const bool support_rwh_write_life;
extern const bool support_rwf_write_life;
// Log facility for ircd::fs
extern log::log log;
}

View file

@ -13,6 +13,20 @@
namespace ircd::fs::support
{
// Runtime-gauged support indicators
extern const bool pwritev2;
extern const bool preadv2;
extern const bool append;
extern const bool nowait;
extern const bool hipri;
extern const bool sync;
extern const bool dsync;
extern const bool rwh_write_life;
extern const bool rwf_write_life;
extern const bool aio;
extern const bool aio_fsync;
extern const bool aio_fdsync;
// Test if O_DIRECT supported at target path
bool direct_io(const string_view &path);

View file

@ -1243,7 +1243,7 @@ try
// Doesn't appear to be in effect when direct io is used. Not supported by
// all filesystems so disabled for now.
// TODO: use fs::support::fallocate() test similar to direct_io_test_file.
// TODO: use fs::support::test_fallocate() test similar to direct_io_test_file.
opts->allow_fallocate = false;
#ifdef RB_DEBUG

View file

@ -26,116 +26,12 @@
// TODO: prevents use until io_uring support implemented
#undef IRCD_USE_IOU
namespace ircd::fs
{
static uint posix_flags(const std::ios::openmode &mode);
static const char *path_str(const string_view &);
}
decltype(ircd::fs::log)
ircd::fs::log
{
"fs"
};
decltype(ircd::fs::support_pwritev2)
ircd::fs::support_pwritev2
{
#if defined(HAVE_PWRITEV2)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 6)
#else
false
#endif
};
decltype(ircd::fs::support_preadv2)
ircd::fs::support_preadv2
{
#if defined(HAVE_PREADV2)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 6)
#else
false
#endif
};
decltype(ircd::fs::support_sync)
ircd::fs::support_sync
{
#if defined(HAVE_PWRITEV2) && defined(RWF_SYNC)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 7)
#else
false
#endif
};
decltype(ircd::fs::support_dsync)
ircd::fs::support_dsync
{
#if defined(HAVE_PWRITEV2) && defined(RWF_DSYNC)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 7)
#else
false
#endif
};
decltype(ircd::fs::support_hipri)
ircd::fs::support_hipri
{
#if defined(HAVE_PWRITEV2) && defined(RWF_HIPRI)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 6)
#else
false
#endif
};
decltype(ircd::fs::support_nowait)
ircd::fs::support_nowait
{
#if defined(HAVE_PWRITEV2) && defined(RWF_NOWAIT)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 14)
#else
false
#endif
};
decltype(ircd::fs::support_append)
ircd::fs::support_append
{
#if defined(HAVE_PWRITEV2) && defined(RWF_APPEND)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 16)
#else
false
#endif
};
decltype(ircd::fs::support_rwh_write_life)
ircd::fs::support_rwh_write_life
{
#if defined(HAVE_FCNTL_H) && defined(F_SET_FILE_RW_HINT)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 13)
#else
false
#endif
};
decltype(ircd::fs::support_rwf_write_life)
ircd::fs::support_rwf_write_life
{
#if defined(RWF_WRITE_LIFE_SHIFT)
false //TODO: XXX
#else
false
#endif
};
//
// init
//
@ -144,21 +40,17 @@ ircd::fs::init::init()
{
const bool support_async
{
false
|| iou::system
|| aio::system
false || iou::system || aio::system
};
if(support_async)
log::info
{
log, "Asynchronous filesystem IO provided by %s %s.",
"Linux",
iou::system?
"io_uring":
aio::system?
"AIO":
"?????",
RB_OS,
iou::system? "io_uring":
aio::system? "AIO":
"?????",
};
else
log::warning
@ -173,6 +65,224 @@ noexcept
{
}
///////////////////////////////////////////////////////////////////////////////
//
// fs/support.h
//
decltype(ircd::fs::support::pwritev2)
ircd::fs::support::pwritev2
{
#if defined(HAVE_PWRITEV2)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 6)
#else
false
#endif
};
decltype(ircd::fs::support::preadv2)
ircd::fs::support::preadv2
{
#if defined(HAVE_PREADV2)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 6)
#else
false
#endif
};
decltype(ircd::fs::support::sync)
ircd::fs::support::sync
{
#if defined(HAVE_PWRITEV2) && defined(RWF_SYNC)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 7)
#else
false
#endif
};
decltype(ircd::fs::support::dsync)
ircd::fs::support::dsync
{
#if defined(HAVE_PWRITEV2) && defined(RWF_DSYNC)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 7)
#else
false
#endif
};
decltype(ircd::fs::support::hipri)
ircd::fs::support::hipri
{
#if defined(HAVE_PWRITEV2) && defined(RWF_HIPRI)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 6)
#else
false
#endif
};
decltype(ircd::fs::support::nowait)
ircd::fs::support::nowait
{
#if defined(HAVE_PWRITEV2) && defined(RWF_NOWAIT)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 14)
#else
false
#endif
};
decltype(ircd::fs::support::append)
ircd::fs::support::append
{
#if defined(HAVE_PWRITEV2) && defined(RWF_APPEND)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 16)
#else
false
#endif
};
decltype(ircd::fs::support::rwh_write_life)
ircd::fs::support::rwh_write_life
{
#if defined(HAVE_FCNTL_H) && defined(F_SET_FILE_RW_HINT)
info::kernel_version[0] > 4 ||
(info::kernel_version[0] >= 4 && info::kernel_version[1] >= 13)
#else
false
#endif
};
decltype(ircd::fs::support::rwf_write_life)
ircd::fs::support::rwf_write_life
{
#if defined(RWF_WRITE_LIFE_SHIFT)
false //TODO: XXX
#else
false
#endif
};
decltype(ircd::fs::support::aio)
ircd::fs::support::aio
{
#ifdef IRCD_USE_AIO
true
#else
false
#endif
};
void
ircd::fs::support::dump_info()
{
#if defined(IRCD_USE_AIO) || defined(IRCD_USE_IOU)
const bool support_async {true};
#else
const bool support_async {false};
#endif
log::info
{
log, "Support: async:%b preadv2:%b pwritev2:%b SYNC:%b DSYNC:%b HIPRI:%b NOWAIT:%b APPEND:%b RWH:%b WLH:%b",
support_async,
preadv2,
pwritev2,
sync,
dsync,
hipri,
nowait,
append,
rwh_write_life,
rwf_write_life,
};
#ifdef RB_DEBUG
const unique_mutable_buffer buf
{
PATH_MAX_LEN + 1
};
log::debug
{
log, "Current working directory: `%s'", cwd(buf)
};
for_each<base>([](const base &base)
{
log::debug
{
log, "Working %s is `%s'",
basepath::get(base).name,
basepath::get(base).path,
};
});
#endif
}
bool
ircd::fs::support::fallocate(const string_view &path,
const write_opts &wopts)
try
{
const fd::opts opts
{
std::ios::out
};
fs::fd fd
{
path, opts
};
fs::allocate(fd, info::page_size, wopts);
return true;
}
catch(const std::system_error &e)
{
const auto &ec(e.code());
if(system_category(ec)) switch(ec.value())
{
case int(std::errc::invalid_argument):
case int(std::errc::operation_not_supported):
return false;
default:
break;
}
throw;
}
bool
ircd::fs::support::direct_io(const string_view &path)
try
{
fd::opts opts{std::ios::out};
opts.direct = true;
fd{path, opts};
return true;
}
catch(const std::system_error &e)
{
const auto &ec(e.code());
if(system_category(ec)) switch(ec.value())
{
case int(std::errc::invalid_argument):
return false;
default:
break;
}
throw;
}
///////////////////////////////////////////////////////////////////////////////
//
// fs.h / misc
@ -323,116 +433,6 @@ catch(const filesystem::filesystem_error &e)
throw error{e};
}
///////////////////////////////////////////////////////////////////////////////
//
// fs/support.h
//
void
ircd::fs::support::dump_info()
{
#if defined(IRCD_USE_AIO) || defined(IRCD_USE_IOU)
const bool support_async {true};
#else
const bool support_async {false};
#endif
log::info
{
log, "Support: async:%b preadv2:%b pwritev2:%b SYNC:%b DSYNC:%b HIPRI:%b NOWAIT:%b APPEND:%b RWH:%b WLH:%b",
support_async,
support_preadv2,
support_pwritev2,
support_sync,
support_dsync,
support_hipri,
support_nowait,
support_append,
support_rwh_write_life,
support_rwf_write_life,
};
#ifdef RB_DEBUG
const unique_mutable_buffer buf
{
PATH_MAX_LEN + 1
};
log::debug
{
log, "Current working directory: `%s'", cwd(buf)
};
for_each<base>([](const base &base)
{
log::debug
{
log, "Working %s is `%s'",
basepath::get(base).name,
basepath::get(base).path,
};
});
#endif
}
bool
ircd::fs::support::fallocate(const string_view &path,
const write_opts &wopts)
try
{
const fd::opts opts
{
std::ios::out
};
fs::fd fd
{
path, opts
};
fs::allocate(fd, info::page_size, wopts);
return true;
}
catch(const std::system_error &e)
{
const auto &ec(e.code());
if(system_category(ec)) switch(ec.value())
{
case int(std::errc::invalid_argument):
case int(std::errc::operation_not_supported):
return false;
default:
break;
}
throw;
}
bool
ircd::fs::support::direct_io(const string_view &path)
try
{
fd::opts opts{std::ios::out};
opts.direct = true;
fd{path, opts};
return true;
}
catch(const std::system_error &e)
{
const auto &ec(e.code());
if(system_category(ec)) switch(ec.value())
{
case int(std::errc::invalid_argument):
return false;
default:
break;
}
throw;
}
///////////////////////////////////////////////////////////////////////////////
//
// fs/stdin.h
@ -560,10 +560,10 @@ ircd::fs::flush(const fd &fd,
#ifdef IRCD_USE_AIO
if(aio::system && opts.aio)
{
if(aio::support_fdsync && !opts.metadata)
if(support::aio_fdsync && !opts.metadata)
return aio::fsync(fd, opts);
if(aio::support_fsync && opts.metadata)
if(support::aio_fsync && opts.metadata)
return aio::fsync(fd, opts);
}
#endif
@ -574,7 +574,7 @@ ircd::fs::flush(const fd &fd,
int(fd),
opts.metadata,
opts.aio,
opts.metadata? aio::support_fsync : aio::support_fdsync
opts.metadata? support::aio_fsync : support::aio_fdsync
};
if(!opts.metadata)
@ -827,7 +827,7 @@ ircd::fs::read(const fd &fd,
#endif
#ifdef HAVE_PREADV2
return support_preadv2?
return support::preadv2?
_read_preadv2(fd, iov, opts):
_read_preadv(fd, iov, opts);
#else
@ -896,12 +896,12 @@ ircd::fs::flags(const read_opts &opts)
int ret{0};
#if defined(RWF_HIPRI)
if(support_hipri && reqprio(opts.priority) == reqprio(opts::highest_priority))
if(support::hipri && reqprio(opts.priority) == reqprio(opts::highest_priority))
ret |= RWF_HIPRI;
#endif
#if defined(RWF_NOWAIT)
if(support_nowait && !opts.blocking)
if(support::nowait && !opts.blocking)
ret |= RWF_NOWAIT;
#endif
@ -1073,7 +1073,7 @@ ircd::fs::append(const fd &fd,
const write_opts &opts_)
{
auto opts(opts_);
if(support_pwritev2 && support_append)
if(support::pwritev2 && support::append)
opts.offset = -1;
else if(!opts.offset || opts.offset == -1)
opts.offset = syscall(::lseek, fd, 0, SEEK_END);
@ -1208,7 +1208,7 @@ ircd::fs::write(const fd &fd,
#endif
#ifdef HAVE_PWRITEV2
return support_pwritev2?
return support::pwritev2?
_write_pwritev2(fd, iov, opts):
_write_pwritev(fd, iov, opts);
#else
@ -1280,33 +1280,33 @@ ircd::fs::flags(const write_opts &opts)
int ret{0};
#if defined(RWF_APPEND)
assert(opts.offset >= 0 || support_append);
if(support_append && opts.offset == -1)
assert(opts.offset >= 0 || support::append);
if(support::append && opts.offset == -1)
ret |= RWF_APPEND;
#endif
#if defined(RWF_HIPRI)
if(support_hipri && reqprio(opts.priority) == reqprio(opts::highest_priority))
if(support::hipri && reqprio(opts.priority) == reqprio(opts::highest_priority))
ret |= RWF_HIPRI;
#endif
#if defined(RWF_NOWAIT)
if(support_nowait && !opts.blocking)
if(support::nowait && !opts.blocking)
ret |= RWF_NOWAIT;
#endif
#if defined(RWF_DSYNC)
if(support_dsync && opts.sync && !opts.metadata)
if(support::dsync && opts.sync && !opts.metadata)
ret |= RWF_DSYNC;
#endif
#if defined(RWF_SYNC)
if(support_sync && opts.sync && opts.metadata)
if(support::sync && opts.sync && opts.metadata)
ret |= RWF_SYNC;
#endif
#ifdef RWF_WRITE_LIFE_SHIFT
if(support_rwf_write_life && opts.write_life)
if(support::rwf_write_life && opts.write_life)
ret |= (opts.write_life << (RWF_WRITE_LIFE_SHIFT));
#endif
@ -1410,16 +1410,6 @@ ircd::fs::reflect(const ready &ready)
// fs/aio.h
//
decltype(ircd::fs::aio::support)
ircd::fs::aio::support
{
#ifdef IRCD_USE_AIO
true
#else
false
#endif
};
decltype(ircd::fs::aio::MAX_REQPRIO)
ircd::fs::aio::MAX_REQPRIO
{
@ -1525,6 +1515,8 @@ noexcept
namespace ircd::fs
{
static const char *path_str(const string_view &);
static uint posix_flags(const std::ios::openmode &mode);
static long pathconf(const fd &, const int &arg);
}
@ -1597,7 +1589,7 @@ void
ircd::fs::write_life(const fd &fd,
const uint64_t &hint)
{
if(!support_rwh_write_life)
if(!support::rwh_write_life)
return;
syscall(::fcntl, int(fd), F_SET_FILE_RW_HINT, &hint);

View file

@ -18,8 +18,8 @@
/// True if IOCB_CMD_FSYNC is supported by AIO. If this is false then
/// fs::fsync_opts::async=true flag is ignored.
decltype(ircd::fs::aio::support_fsync)
ircd::fs::aio::support_fsync
decltype(ircd::fs::support::aio_fsync)
ircd::fs::support::aio_fsync
{
#if defined(RWF_SYNC)
info::kernel_version[0] > 4 ||
@ -31,8 +31,8 @@ ircd::fs::aio::support_fsync
/// True if IOCB_CMD_FDSYNC is supported by AIO. If this is false then
/// fs::fsync_opts::async=true flag is ignored.
decltype(ircd::fs::aio::support_fdsync)
ircd::fs::aio::support_fdsync
decltype(ircd::fs::support::aio_fdsync)
ircd::fs::support::aio_fdsync
{
#if defined(RWF_DSYNC)
info::kernel_version[0] > 4 ||
@ -202,7 +202,7 @@ ircd::fs::aio::read(const fd &fd,
stats.max_reads = std::max(stats.max_reads, stats.cur_reads);
#if defined(RWF_NOWAIT) && defined(RB_DEBUG_FS_AIO_READ_BLOCKING)
request.aio_rw_flags |= support_nowait? RWF_NOWAIT : 0;
request.aio_rw_flags |= support::nowait? RWF_NOWAIT : 0;
#endif
size_t bytes
@ -263,7 +263,7 @@ ircd::fs::aio::request::write::write(const int &fd,
aio_offset = opts.offset;
#if defined(RWF_APPEND)
if(support_append && opts.offset == -1)
if(support::append && opts.offset == -1)
{
// AIO departs from pwritev2() behavior and EINVAL's on -1.
aio_offset = 0;
@ -272,17 +272,17 @@ ircd::fs::aio::request::write::write(const int &fd,
#endif
#if defined(RWF_DSYNC)
if(support_dsync && opts.sync && !opts.metadata)
if(support::dsync && opts.sync && !opts.metadata)
aio_rw_flags |= RWF_DSYNC;
#endif
#if defined(RWF_SYNC)
if(support_sync && opts.sync && opts.metadata)
if(support::sync && opts.sync && opts.metadata)
aio_rw_flags |= RWF_SYNC;
#endif
#ifdef RWF_WRITE_LIFE_SHIFT
if(support_rwf_write_life && opts.write_life)
if(support::rwf_write_life && opts.write_life)
aio_rw_flags |= (opts.write_life << (RWF_WRITE_LIFE_SHIFT));
#endif
}
@ -384,12 +384,12 @@ ircd::fs::aio::request::request(const int &fd,
aio_reqprio = reqprio(opts->priority);
#if defined(RWF_HIPRI)
if(support_hipri && aio_reqprio == reqprio(opts::highest_priority))
if(support::hipri && aio_reqprio == reqprio(opts::highest_priority))
aio_rw_flags |= RWF_HIPRI;
#endif
#if defined(RWF_NOWAIT)
if(support_nowait && !opts->blocking)
if(support::nowait && !opts->blocking)
aio_rw_flags |= RWF_NOWAIT;
#endif
}