0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 07:23:53 +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.
namespace ircd::fs
{
struct aio;
struct init;
enum index :int;
struct error; // custom exception; still inherits from ircd::error
constexpr size_t PATH_MAX { 2048 };
extern aio *aioctx;
string_view get(index) noexcept;
string_view name(index) noexcept;
std::string make_path(const vector_view<const string_view> &);
@ -85,6 +82,7 @@ enum ircd::fs::index
#include "error.h"
#include "fd.h"
#include "aio.h"
#include "read.h"
#include "write.h"
#include "fsync.h"
@ -92,6 +90,8 @@ enum ircd::fs::index
struct ircd::fs::init
{
aio::init _aio_;
init();
~init() noexcept;
};

View file

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

View file

@ -12,21 +12,21 @@
#define HAVE_AIO_H
#include <linux/aio_abi.h>
namespace ircd::fs
{
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
namespace ircd::fs::aio
{
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
static const size_t MAX_EVENTS;
@ -56,8 +56,8 @@ struct ircd::fs::aio
bool wait();
bool interrupt();
aio();
~aio() noexcept;
kernel();
~kernel() noexcept;
};
/// Generic request control block.
@ -69,9 +69,9 @@ struct ircd::fs::aio::request
struct fdsync;
struct fsync;
ctx::ctx *waiter {ctx::current};
ssize_t retval {std::numeric_limits<ssize_t>::min()};
ssize_t errcode {0};
ctx::ctx *waiter {ctx::current};
public:
size_t operator()();

1325
ircd/fs.cc

File diff suppressed because it is too large Load diff