0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd::fs: Abstract the common options into opts struct.

This commit is contained in:
Jason Volk 2018-12-29 20:02:22 -08:00
parent 3bec2c27d4
commit 663b164f39
8 changed files with 85 additions and 92 deletions

View file

@ -33,6 +33,7 @@ namespace ircd::fs
#include "error.h" #include "error.h"
#include "path.h" #include "path.h"
#include "iov.h" #include "iov.h"
#include "opts.h"
#include "fd.h" #include "fd.h"
#include "aio.h" #include "aio.h"
#include "read.h" #include "read.h"

47
include/ircd/fs/opts.h Normal file
View file

@ -0,0 +1,47 @@
// 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_SYNC_OPTS_H
namespace ircd::fs
{
struct opts extern const opts_default;
}
/// Options common to all operations
struct ircd::fs::opts
{
/// Offset in the file.
off_t offset {0};
/// Request priority. Lower value takes priority over higher.
int8_t priority {0};
/// Submits the I/O request immediately rather than allowing IRCd to
/// queue requests for a few iterations of the ircd::ios event loop.
/// (only relevant to aio).
bool nodelay {false};
/// Determines whether this operation is conducted via AIO. If not, a
/// direct syscall is made. Using AIO will only block one ircd::ctx while
/// a direct syscall will block the thread (all contexts). If AIO is not
/// available or not enabled, or doesn't support this operation, setting
/// this has no effect.
bool aio {true};
opts(const off_t &);
opts() = default;
};
inline
ircd::fs::opts::opts(const off_t &offset)
:offset{offset}
{}

View file

@ -33,23 +33,8 @@ namespace ircd::fs
/// Options for a read operation /// Options for a read operation
struct ircd::fs::read_opts struct ircd::fs::read_opts
:opts
{ {
read_opts() = default;
read_opts(const off_t &);
/// Offset in the file to start the read from.
off_t offset {0};
/// Request priority. Lower value request will take priority over higher
int8_t priority {0};
/// Determines whether this operation is conducted via AIO. If not, a
/// direct syscall is made. Using AIO will only block one ircd::ctx while
/// a direct syscall will block the thread (all contexts). If AIO is not
/// available or not enabled, or doesn't support this operation, setting
/// this has no effect.
bool aio {true};
/// Yields the ircd::ctx until the buffers are full or EOF. This performs /// Yields the ircd::ctx until the buffers are full or EOF. This performs
/// the unix incremental read loop internally. When this option is true, /// the unix incremental read loop internally. When this option is true,
/// any return value from a function in the read suite will not be a /// any return value from a function in the read suite will not be a
@ -62,13 +47,11 @@ struct ircd::fs::read_opts
/// in the useful propagation of an exception for this event. /// in the useful propagation of an exception for this event.
bool interruptible {true}; bool interruptible {true};
/// Submits the I/O request immediately rather than allowing IRCd to read_opts(const off_t &);
/// queue requests for a few iterations of the ircd::ios event loop. read_opts() = default;
/// (only relevant to aio).
bool nodelay {false};
}; };
inline inline
ircd::fs::read_opts::read_opts(const off_t &offset) ircd::fs::read_opts::read_opts(const off_t &offset)
:offset{offset} :opts{offset}
{} {}

View file

@ -24,21 +24,18 @@ namespace ircd::fs
/// Options for a write operation /// Options for a write operation
struct ircd::fs::sync_opts struct ircd::fs::sync_opts
:opts
{ {
sync_opts() = default;
/// Set to true to flush metadata; otherwise only data is flushed. /// Set to true to flush metadata; otherwise only data is flushed.
/// This ends up forcing the use of fsync() rather than fdatasync() or /// This ends up forcing the use of fsync() rather than fdatasync() or
/// sync_file_range() et al. /// sync_file_range() et al.
bool metadata {true}; bool metadata {true};
/// Determines whether this operation is conducted via AIO. If not, a sync_opts(const off_t &offset);
/// direct syscall is made. Using AIO will only block one ircd::ctx while sync_opts() = default;
/// a direct syscall will block the thread (all contexts). If AIO is not
/// available or not enabled, or doesn't support this operation, setting
/// this has no effect.
bool aio {true};
/// Request priority. This value is ignored for sync operations.
int8_t priority {0};
}; };
inline
ircd::fs::sync_opts::sync_opts(const off_t &offset)
:opts{offset}
{}

View file

@ -49,29 +49,11 @@ namespace ircd::fs
/// Options for a write operation /// Options for a write operation
struct ircd::fs::write_opts struct ircd::fs::write_opts
:opts
{ {
write_opts() = default;
write_opts(const off_t &);
/// Offset in the file to start the write from. For append() if this zero
/// then it will be internally set to the end of the file; otherwise if
/// this is set it will write to that offset, even for append(), unless
/// the host system later ignores the offset due to the file's openmode.
off_t offset {0};
/// Request priority. Lower value request will take priority over higher.
int8_t priority {0};
/// for allocate() /// for allocate()
bool keep_size {false}; bool keep_size {false};
/// Determines whether this operation is conducted via AIO. If not, a
/// direct syscall is made. Using AIO will only block one ircd::ctx while
/// a direct syscall will block the thread (all contexts). If AIO is not
/// available or not enabled, or doesn't support this operation, setting
/// this has no effect.
bool aio {true};
/// Yields the ircd::ctx until the buffers are written. This performs /// Yields the ircd::ctx until the buffers are written. This performs
/// the unix incremental write loop internally. When this option is true, /// the unix incremental write loop internally. When this option is true,
/// any return value from a function in the write() suite will not be a /// any return value from a function in the write() suite will not be a
@ -84,13 +66,11 @@ struct ircd::fs::write_opts
/// in the useful propagation of an exception for this event. /// in the useful propagation of an exception for this event.
bool interruptible {true}; bool interruptible {true};
/// Submits the I/O request immediately rather than allowing IRCd to write_opts(const off_t &);
/// queue requests for a few iterations of the ircd::ios event loop. write_opts() = default;
/// (only relevant to aio).
bool nodelay {false};
}; };
inline inline
ircd::fs::write_opts::write_opts(const off_t &offset) ircd::fs::write_opts::write_opts(const off_t &offset)
:offset{offset} :opts{offset}
{} {}

View file

@ -92,10 +92,8 @@ noexcept
ircd::fs::aio::request::fsync::fsync(const int &fd, ircd::fs::aio::request::fsync::fsync(const int &fd,
const sync_opts &opts) const sync_opts &opts)
:request{fd} :request{fd, &opts}
{ {
sopts = &opts;
aio_reqprio = reqprio(opts.priority); aio_reqprio = reqprio(opts.priority);
aio_lio_opcode = IOCB_CMD_FSYNC; aio_lio_opcode = IOCB_CMD_FSYNC;
@ -122,10 +120,8 @@ ircd::fs::aio::fsync(const fd &fd,
ircd::fs::aio::request::fdsync::fdsync(const int &fd, ircd::fs::aio::request::fdsync::fdsync(const int &fd,
const sync_opts &opts) const sync_opts &opts)
:request{fd} :request{fd, &opts}
{ {
sopts = &opts;
aio_reqprio = reqprio(opts.priority); aio_reqprio = reqprio(opts.priority);
aio_lio_opcode = IOCB_CMD_FDSYNC; aio_lio_opcode = IOCB_CMD_FDSYNC;
@ -153,10 +149,8 @@ ircd::fs::aio::fdsync(const fd &fd,
ircd::fs::aio::request::read::read(const int &fd, ircd::fs::aio::request::read::read(const int &fd,
const const_iovec_view &iov, const const_iovec_view &iov,
const read_opts &opts) const read_opts &opts)
:request{fd} :request{fd, &opts}
{ {
ropts = &opts;
aio_reqprio = reqprio(opts.priority); aio_reqprio = reqprio(opts.priority);
aio_lio_opcode = IOCB_CMD_PREADV; aio_lio_opcode = IOCB_CMD_PREADV;
@ -200,10 +194,8 @@ ircd::fs::aio::read(const fd &fd,
ircd::fs::aio::request::write::write(const int &fd, ircd::fs::aio::request::write::write(const int &fd,
const const_iovec_view &iov, const const_iovec_view &iov,
const write_opts &opts) const write_opts &opts)
:request{fd} :request{fd, &opts}
{ {
wopts = &opts;
aio_reqprio = reqprio(opts.priority); aio_reqprio = reqprio(opts.priority);
aio_lio_opcode = IOCB_CMD_PWRITEV; aio_lio_opcode = IOCB_CMD_PWRITEV;
@ -268,8 +260,10 @@ ircd::fs::aio::prefetch(const fd &fd,
// request // request
// //
ircd::fs::aio::request::request(const int &fd) ircd::fs::aio::request::request(const int &fd,
const struct opts *const &opts)
:iocb{0} :iocb{0}
,opts{opts}
{ {
assert(system); assert(system);
assert(ctx::current); assert(ctx::current);
@ -543,6 +537,7 @@ ircd::fs::aio::system::cancel(request &request)
void void
ircd::fs::aio::system::submit(request &request) ircd::fs::aio::system::submit(request &request)
{ {
assert(request.opts);
assert(qcount < queue.size()); assert(qcount < queue.size());
assert(qcount + in_flight < max_events); assert(qcount + in_flight < max_events);
assert(request.aio_data == uintptr_t(&request)); assert(request.aio_data == uintptr_t(&request));
@ -552,25 +547,10 @@ ircd::fs::aio::system::submit(request &request)
stats.cur_queued++; stats.cur_queued++;
// Determine whether the user wants (or needs) to submit without delay. // Determine whether the user wants (or needs) to submit without delay.
bool nodelay; switch(request.aio_lio_opcode)
{
case IOCB_CMD_PREADV:
nodelay = request.ropts->nodelay;
break;
case IOCB_CMD_PWRITEV:
nodelay = request.wopts->nodelay;
break;
default:
nodelay = true;
break;
}
const bool submit_now const bool submit_now
{ {
// The nodelay flag is set // The nodelay flag is set
nodelay request.opts->nodelay
// The queue has reached the configured size // The queue has reached the configured size
|| qcount >= size_t(max_submit) || qcount >= size_t(max_submit)

View file

@ -83,12 +83,8 @@ struct ircd::fs::aio::request
ctx::ctx *waiter {ctx::current}; 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}; union ssize_t errcode {0};
{ const struct opts *opts {nullptr};
const read_opts *ropts {nullptr};
const write_opts *wopts;
const sync_opts *sopts;
};
public: public:
const_iovec_view iovec() const; const_iovec_view iovec() const;
@ -96,7 +92,7 @@ struct ircd::fs::aio::request
size_t operator()(); size_t operator()();
void cancel(); void cancel();
request(const int &fd); request(const int &fd, const struct opts *const &);
~request() noexcept; ~request() noexcept;
}; };

View file

@ -1124,6 +1124,15 @@ noexcept(false)
syscall(::close, fdno); syscall(::close, fdno);
} }
///////////////////////////////////////////////////////////////////////////////
//
// fs/opts.h
//
decltype(ircd::fs::opts_default)
ircd::fs::opts_default
{};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// fs/iov.h // fs/iov.h