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:
parent
0de55ce111
commit
062906143f
5 changed files with 771 additions and 694 deletions
32
include/ircd/fs/aio.h
Normal file
32
include/ircd/fs/aio.h
Normal 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;
|
||||||
|
};
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
72
ircd/aio.cc
72
ircd/aio.cc
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
30
ircd/aio.h
30
ircd/aio.h
|
@ -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
1325
ircd/fs.cc
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue