diff --git a/include/ircd/fs/fs.h b/include/ircd/fs/fs.h index 34493b66d..6dd5c9928 100644 --- a/include/ircd/fs/fs.h +++ b/include/ircd/fs/fs.h @@ -86,6 +86,7 @@ enum ircd::fs::index #include "fd.h" #include "read.h" #include "write.h" +#include "fsync.h" #include "stdin.h" struct ircd::fs::init diff --git a/include/ircd/fs/fsync.h b/include/ircd/fs/fsync.h new file mode 100644 index 000000000..80048a598 --- /dev/null +++ b/include/ircd/fs/fsync.h @@ -0,0 +1,29 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_FS_FSYNC_H + +namespace ircd::fs +{ + struct fsync_opts extern const fsync_opts_default; + + void fdsync(const fd &, const fsync_opts & = fsync_opts_default); + void fsync(const fd &, const fsync_opts & = fsync_opts_default); +} + +/// Options for a write operation +struct ircd::fs::fsync_opts +{ + fsync_opts() = default; + + /// Request priority (this option may be improved, avoid for now) + int16_t priority {0}; +}; diff --git a/ircd/aio.cc b/ircd/aio.cc index 07debb994..1a1080764 100644 --- a/ircd/aio.cc +++ b/ircd/aio.cc @@ -12,6 +12,62 @@ #include #include "aio.h" +// +// request::fsync +// + +ircd::fs::aio::request::fsync::fsync(const int &fd, + const fsync_opts &opts) +:request{fd} +{ + aio_reqprio = opts.priority; + aio_lio_opcode = IOCB_CMD_FSYNC; + + aio_buf = 0; + aio_nbytes = 0; + aio_offset = 0; +} + +void +ircd::fs::fsync__aio(const fd &fd, + const fsync_opts &opts) +{ + aio::request::fsync request + { + fd, opts + }; + + request(); +} + +// +// request::fdsync +// + +ircd::fs::aio::request::fdsync::fdsync(const int &fd, + const fsync_opts &opts) +:request{fd} +{ + aio_reqprio = opts.priority; + aio_lio_opcode = IOCB_CMD_FDSYNC; + + aio_buf = 0; + aio_nbytes = 0; + aio_offset = 0; +} + +void +ircd::fs::fdsync__aio(const fd &fd, + const fsync_opts &opts) +{ + aio::request::fdsync request + { + fd, opts + }; + + request(); +} + // // request::read // @@ -212,7 +268,7 @@ noexcept try // The count should be at least 1 event. The only reason to return 0 might // be related to an INTR; this assert will find out and may be commented. - assert(count > 0); + //assert(count > 0); for(ssize_t i(0); i < count; ++i) handle_event(event[i]); diff --git a/ircd/aio.h b/ircd/aio.h index e060d52fe..0ad3422c8 100644 --- a/ircd/aio.h +++ b/ircd/aio.h @@ -21,7 +21,7 @@ struct ircd::fs::aio struct request; /// Maximum number of events we can submit to kernel - static constexpr const size_t &MAX_EVENTS {64}; + static constexpr const size_t &MAX_EVENTS {512}; /// Internal semaphore for synchronization of this object ctx::dock dock; @@ -46,7 +46,7 @@ struct ircd::fs::aio void handle(const boost::system::error_code &, const size_t) noexcept; void set_handle(); - bool wait_interrupt(); + bool wait(); bool interrupt(); aio(); @@ -59,6 +59,8 @@ struct ircd::fs::aio::request { struct read; struct write; + struct fdsync; + struct fsync; ssize_t retval {std::numeric_limits::min()}; ssize_t errcode {0}; @@ -76,6 +78,8 @@ namespace ircd::fs { const_buffer write__aio(const fd &, const const_buffer &, const write_opts &); const_buffer read__aio(const fd &, const mutable_buffer &, const read_opts &); + void fdsync__aio(const fd &, const fsync_opts &); + void fsync__aio(const fd &, const fsync_opts &); } /// Read request control block @@ -91,3 +95,17 @@ struct ircd::fs::aio::request::write { write(const int &fd, const const_buffer &, const write_opts &); }; + +/// fdsync request control block +struct ircd::fs::aio::request::fdsync +:request +{ + fdsync(const int &fd, const fsync_opts &); +}; + +/// fsync request control block +struct ircd::fs::aio::request::fsync +:request +{ + fsync(const int &fd, const fsync_opts &); +}; diff --git a/ircd/fs.cc b/ircd/fs.cc index 0674e406b..b82b6081f 100644 --- a/ircd/fs.cc +++ b/ircd/fs.cc @@ -163,6 +163,60 @@ ircd::fs::stdin::tty::write(const string_view &buf) return syscall(::write, int(*this), buf.data(), buf.size()); } +/////////////////////////////////////////////////////////////////////////////// +// +// fs/fsync.h +// + +ircd::fs::fsync_opts +const ircd::fs::fsync_opts_default +{}; + +void +ircd::fs::fsync(const fd &fd, + const fsync_opts &opts) +try +{ + #ifdef IRCD_USE_AIO + if(likely(aioctx)) + return fsync__aio(fd, opts); + #endif + + syscall(::fsync, fd); +} +catch(const std::exception &e) +{ + throw filesystem_error + { + "%s", e.what() + }; +} + +void +ircd::fs::fdsync(const fd &fd, + const fsync_opts &opts) +try +{ + #ifdef IRCD_USE_AIO + if(likely(aioctx)) + return fdsync__aio(fd, opts); + #endif + + syscall(::fdatasync, fd); +} +catch(const std::exception &e) +{ + throw filesystem_error + { + "%s", e.what() + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// fs/prefetch.h +// + /////////////////////////////////////////////////////////////////////////////// // // fs/read.h @@ -172,10 +226,6 @@ ircd::fs::read_opts const ircd::fs::read_opts_default {}; -// -// ircd::fs interface linkage -// - #ifdef __linux__ void ircd::fs::prefetch(const fd &fd,