0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::fs: Add an fs/aio.h header. Reorg various aio namespace related.

This commit is contained in:
Jason Volk 2018-11-27 18:09:12 -08:00
parent 0de55ce111
commit 062906143f
5 changed files with 771 additions and 694 deletions

32
include/ircd/fs/aio.h Normal file
View file

@ -0,0 +1,32 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// 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_AIO_H
// Public and unconditional interface for Linux AIO. This file is part of
// the standard include stack and available whether or not this platform
// is Linux with AIO, and whether or not it's enabled, etc. If it is not
// most of this stuff does nothing and will have null values.
//
namespace ircd::fs::aio
{
struct init;
struct kernel;
struct request;
extern kernel *context;
}
struct ircd::fs::aio::init
{
init();
~init() noexcept;
};

View file

@ -34,15 +34,12 @@
/// during IOs. /// during IOs.
namespace ircd::fs namespace ircd::fs
{ {
struct aio;
struct init; struct init;
enum index :int; enum index :int;
struct error; // custom exception; still inherits from ircd::error struct error; // custom exception; still inherits from ircd::error
constexpr size_t PATH_MAX { 2048 }; constexpr size_t PATH_MAX { 2048 };
extern aio *aioctx;
string_view get(index) noexcept; string_view get(index) noexcept;
string_view name(index) noexcept; string_view name(index) noexcept;
std::string make_path(const vector_view<const string_view> &); std::string make_path(const vector_view<const string_view> &);
@ -85,6 +82,7 @@ enum ircd::fs::index
#include "error.h" #include "error.h"
#include "fd.h" #include "fd.h"
#include "aio.h"
#include "read.h" #include "read.h"
#include "write.h" #include "write.h"
#include "fsync.h" #include "fsync.h"
@ -92,6 +90,8 @@ enum ircd::fs::index
struct ircd::fs::init struct ircd::fs::init
{ {
aio::init _aio_;
init(); init();
~init() noexcept; ~init() noexcept;
}; };

View file

@ -13,11 +13,16 @@
#include <ircd/asio.h> #include <ircd/asio.h>
#include "aio.h" #include "aio.h"
namespace ircd::fs namespace ircd::fs::aio
{ {
static int reqprio(int); static int reqprio(int);
} }
///////////////////////////////////////////////////////////////////////////////
//
// ircd/aio.h (internal)
//
// //
// request::fsync // request::fsync
// //
@ -35,7 +40,7 @@ ircd::fs::aio::request::fsync::fsync(const int &fd,
} }
void void
ircd::fs::fsync__aio(const fd &fd, ircd::fs::aio::fsync(const fd &fd,
const fsync_opts &opts) const fsync_opts &opts)
{ {
aio::request::fsync request aio::request::fsync request
@ -63,7 +68,7 @@ ircd::fs::aio::request::fdsync::fdsync(const int &fd,
} }
void void
ircd::fs::fdsync__aio(const fd &fd, ircd::fs::aio::fdsync(const fd &fd,
const fsync_opts &opts) const fsync_opts &opts)
{ {
aio::request::fdsync request aio::request::fdsync request
@ -100,7 +105,7 @@ ircd::fs::aio::request::read::read(const int &fd,
} }
ircd::const_buffer ircd::const_buffer
ircd::fs::read__aio(const fd &fd, ircd::fs::aio::read(const fd &fd,
const mutable_buffer &buf, const mutable_buffer &buf,
const read_opts &opts) const read_opts &opts)
{ {
@ -148,7 +153,7 @@ ircd::fs::aio::request::write::write(const int &fd,
} }
ircd::const_buffer ircd::const_buffer
ircd::fs::write__aio(const fd &fd, ircd::fs::aio::write(const fd &fd,
const const_buffer &buf, const const_buffer &buf,
const write_opts &opts) const write_opts &opts)
{ {
@ -175,7 +180,7 @@ ircd::fs::write__aio(const fd &fd,
// //
void void
ircd::fs::prefetch__aio(const fd &fd, ircd::fs::aio::prefetch(const fd &fd,
const size_t &size, const size_t &size,
const read_opts &opts) const read_opts &opts)
{ {
@ -187,7 +192,7 @@ ircd::fs::prefetch__aio(const fd &fd,
// //
int int
ircd::fs::reqprio(int input) ircd::fs::aio::reqprio(int input)
{ {
// no use for negative values yet; make them zero. // no use for negative values yet; make them zero.
input = std::max(input, 0); input = std::max(input, 0);
@ -199,20 +204,20 @@ ircd::fs::reqprio(int input)
} }
// //
// aio // kernel
// //
decltype(ircd::fs::aio::MAX_EVENTS) decltype(ircd::fs::aio::kernel::MAX_EVENTS)
ircd::fs::aio::MAX_EVENTS ircd::fs::aio::kernel::MAX_EVENTS
{ {
512 512
}; };
// //
// aio::aio // kernel::kernel
// //
ircd::fs::aio::aio() ircd::fs::aio::kernel::kernel()
try try
:resfd :resfd
{ {
@ -237,7 +242,7 @@ catch(const std::exception &e)
}; };
} }
ircd::fs::aio::~aio() ircd::fs::aio::kernel::~kernel()
noexcept try noexcept try
{ {
const ctx::uninterruptible::nothrow ui; const ctx::uninterruptible::nothrow ui;
@ -261,7 +266,7 @@ catch(const std::exception &e)
} }
bool bool
ircd::fs::aio::interrupt() ircd::fs::aio::kernel::interrupt()
{ {
if(!resfd.is_open()) if(!resfd.is_open())
return false; return false;
@ -271,7 +276,7 @@ ircd::fs::aio::interrupt()
} }
bool bool
ircd::fs::aio::wait() ircd::fs::aio::kernel::wait()
{ {
if(!resfd.is_open()) if(!resfd.is_open())
return false; return false;
@ -290,18 +295,27 @@ ircd::fs::aio::wait()
} }
void void
ircd::fs::aio::set_handle() ircd::fs::aio::kernel::set_handle()
{ {
semval = 0; semval = 0;
const asio::mutable_buffers_1 bufs(&semval, sizeof(semval));
auto handler{std::bind(&aio::handle, this, ph::_1, ph::_2)}; const asio::mutable_buffers_1 bufs
{
&semval, sizeof(semval)
};
auto handler
{
std::bind(&kernel::handle, this, ph::_1, ph::_2)
};
asio::async_read(resfd, bufs, std::move(handler)); asio::async_read(resfd, bufs, std::move(handler));
} }
/// Handle notifications that requests are complete. /// Handle notifications that requests are complete.
void void
ircd::fs::aio::handle(const boost::system::error_code &ec, ircd::fs::aio::kernel::handle(const boost::system::error_code &ec,
const size_t bytes) const size_t bytes)
noexcept try noexcept try
{ {
namespace errc = boost::system::errc; namespace errc = boost::system::errc;
@ -336,7 +350,7 @@ catch(const ctx::interrupted &)
} }
void void
ircd::fs::aio::handle_events() ircd::fs::aio::kernel::handle_events()
noexcept try noexcept try
{ {
assert(!ctx::current); assert(!ctx::current);
@ -368,7 +382,7 @@ catch(const std::exception &e)
} }
void void
ircd::fs::aio::handle_event(const io_event &event) ircd::fs::aio::kernel::handle_event(const io_event &event)
noexcept try noexcept try
{ {
// Our extended control block is passed in event.data // Our extended control block is passed in event.data
@ -426,11 +440,11 @@ catch(const std::exception &e)
ircd::fs::aio::request::request(const int &fd) ircd::fs::aio::request::request(const int &fd)
:iocb{0} :iocb{0}
{ {
assert(aioctx); assert(context);
assert(ctx::current); assert(ctx::current);
aio_flags = IOCB_FLAG_RESFD; aio_flags = IOCB_FLAG_RESFD;
aio_resfd = aioctx->resfd.native_handle(); aio_resfd = context->resfd.native_handle();
aio_fildes = fd; aio_fildes = fd;
aio_data = uintptr_t(this); aio_data = uintptr_t(this);
} }
@ -449,9 +463,9 @@ ircd::fs::aio::request::cancel()
io_event result {0}; io_event result {0};
const auto &cb{static_cast<iocb *>(this)}; const auto &cb{static_cast<iocb *>(this)};
assert(aioctx); assert(context);
syscall_nointr<SYS_io_cancel>(aioctx->idp, cb, &result); syscall_nointr<SYS_io_cancel>(context->idp, cb, &result);
aioctx->handle_event(result); context->handle_event(result);
} }
/// Submit a request and properly yield the ircd::ctx. When this returns the /// Submit a request and properly yield the ircd::ctx. When this returns the
@ -460,7 +474,7 @@ size_t
ircd::fs::aio::request::operator()() ircd::fs::aio::request::operator()()
try try
{ {
assert(aioctx); assert(context);
assert(ctx::current); assert(ctx::current);
assert(waiter == ctx::current); assert(waiter == ctx::current);
@ -469,7 +483,7 @@ try
static_cast<iocb *>(this) static_cast<iocb *>(this)
}; };
syscall<SYS_io_submit>(aioctx->idp, 1, &cbs); do syscall<SYS_io_submit>(context->idp, 1, &cbs); do
{ {
ctx::wait(); ctx::wait();
} }

View file

@ -12,21 +12,21 @@
#define HAVE_AIO_H #define HAVE_AIO_H
#include <linux/aio_abi.h> #include <linux/aio_abi.h>
namespace ircd::fs namespace ircd::fs::aio
{
void prefetch__aio(const fd &, const size_t &, const read_opts &);
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 &);
}
/// AIO context instance. Right now this is a singleton with an extern
/// instance at fs::aioctx.
struct ircd::fs::aio
{ {
struct request; struct request;
void prefetch(const fd &, const size_t &, const read_opts &);
const_buffer write(const fd &, const const_buffer &, const write_opts &);
const_buffer read(const fd &, const mutable_buffer &, const read_opts &);
void fdsync(const fd &, const fsync_opts &);
void fsync(const fd &, const fsync_opts &);
}
/// AIO context instance from the kernel. Right now this is a singleton with
/// an extern instance pointer at fs::aio::context maintained by fs::aio::init.
struct ircd::fs::aio::kernel
{
/// Maximum number of events we can submit to kernel /// Maximum number of events we can submit to kernel
static const size_t MAX_EVENTS; static const size_t MAX_EVENTS;
@ -56,8 +56,8 @@ struct ircd::fs::aio
bool wait(); bool wait();
bool interrupt(); bool interrupt();
aio(); kernel();
~aio() noexcept; ~kernel() noexcept;
}; };
/// Generic request control block. /// Generic request control block.
@ -69,9 +69,9 @@ struct ircd::fs::aio::request
struct fdsync; struct fdsync;
struct fsync; struct fsync;
ctx::ctx *waiter {ctx::current};
ssize_t retval {std::numeric_limits<ssize_t>::min()}; ssize_t retval {std::numeric_limits<ssize_t>::min()};
ssize_t errcode {0}; ssize_t errcode {0};
ctx::ctx *waiter {ctx::current};
public: public:
size_t operator()(); size_t operator()();

1325
ircd/fs.cc

File diff suppressed because it is too large Load diff