diff --git a/include/ircd/fs/aio.h b/include/ircd/fs/aio.h index 4ed1bc003..8be061df7 100644 --- a/include/ircd/fs/aio.h +++ b/include/ircd/fs/aio.h @@ -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; diff --git a/include/ircd/fs/fs.h b/include/ircd/fs/fs.h index df88e589f..58889525c 100644 --- a/include/ircd/fs/fs.h +++ b/include/ircd/fs/fs.h @@ -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; } diff --git a/include/ircd/fs/support.h b/include/ircd/fs/support.h index a7d853267..98b158a5d 100644 --- a/include/ircd/fs/support.h +++ b/include/ircd/fs/support.h @@ -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); diff --git a/ircd/db.cc b/ircd/db.cc index 341e4c3bf..476319f5a 100644 --- a/ircd/db.cc +++ b/ircd/db.cc @@ -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 diff --git a/ircd/fs.cc b/ircd/fs.cc index c2f19f765..305d030f4 100644 --- a/ircd/fs.cc +++ b/ircd/fs.cc @@ -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([](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([](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); diff --git a/ircd/fs_aio.cc b/ircd/fs_aio.cc index c8d27e172..07cb00b42 100644 --- a/ircd/fs_aio.cc +++ b/ircd/fs_aio.cc @@ -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 }