mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd::fs: Add interface to mmap fd.
This commit is contained in:
parent
c863e09f08
commit
f6475a2906
3 changed files with 184 additions and 0 deletions
|
@ -47,6 +47,7 @@ namespace ircd::fs
|
|||
#include "opts.h"
|
||||
#include "dev.h"
|
||||
#include "fd.h"
|
||||
#include "map.h"
|
||||
#include "wait.h"
|
||||
#include "read.h"
|
||||
#include "write.h"
|
||||
|
|
57
include/ircd/fs/map.h
Normal file
57
include/ircd/fs/map.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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_MAP_H
|
||||
|
||||
namespace ircd::fs
|
||||
{
|
||||
struct map;
|
||||
}
|
||||
|
||||
/// Interface to map file into memory.
|
||||
///
|
||||
/// Note that this was created specifically for file maps and not intended to
|
||||
/// be a generic mmap(2) interface, at least for now.
|
||||
struct ircd::fs::map
|
||||
:mutable_buffer
|
||||
{
|
||||
struct opts;
|
||||
|
||||
map() = default;
|
||||
map(const fd &, const opts &opts, const size_t &size = 0UL);
|
||||
map(map &&) noexcept;
|
||||
map(const map &) = delete;
|
||||
map &operator=(map &&) noexcept;
|
||||
map &operator=(const map &) = delete;
|
||||
~map() noexcept;
|
||||
};
|
||||
|
||||
/// Descriptor options (open options)
|
||||
struct ircd::fs::map::opts
|
||||
:fd::opts
|
||||
{
|
||||
bool execute {false};
|
||||
bool shared {false};
|
||||
bool reserve {false};
|
||||
bool populate {false};
|
||||
|
||||
opts(const fd::opts &opts = {std::ios::in})
|
||||
:fd::opts(opts)
|
||||
{}
|
||||
};
|
||||
|
||||
inline
|
||||
ircd::fs::map::map(map &&other)
|
||||
noexcept
|
||||
:mutable_buffer{other}
|
||||
{
|
||||
static_cast<mutable_buffer &>(other) = {};
|
||||
}
|
126
ircd/fs.cc
126
ircd/fs.cc
|
@ -1730,6 +1730,132 @@ noexcept
|
|||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// fs/map.h
|
||||
//
|
||||
|
||||
namespace ircd::fs
|
||||
{
|
||||
static uint flags(const map::opts &);
|
||||
static uint prot(const map::opts &);
|
||||
}
|
||||
|
||||
ircd::fs::map::map(const fd &fd,
|
||||
const opts &opts,
|
||||
const size_t &size)
|
||||
{
|
||||
const auto map_size
|
||||
{
|
||||
size?: fs::size(fd)
|
||||
};
|
||||
|
||||
void *const &ptr
|
||||
{
|
||||
::mmap(nullptr, map_size, prot(opts), flags(opts), int(fd), opts.offset)
|
||||
};
|
||||
|
||||
if(unlikely(ptr == MAP_FAILED))
|
||||
throw_system_error(errno);
|
||||
|
||||
static_cast<mutable_buffer &>(*this) = mutable_buffer
|
||||
{
|
||||
reinterpret_cast<char *>(ptr),
|
||||
map_size
|
||||
};
|
||||
}
|
||||
|
||||
ircd::fs::map::~map()
|
||||
noexcept try
|
||||
{
|
||||
if(mutable_buffer::null())
|
||||
return;
|
||||
|
||||
syscall(::munmap, data(*this), size(*this));
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::critical
|
||||
{
|
||||
log, "munmap(%p, %zu) :%s",
|
||||
data(static_cast<mutable_buffer &>(*this)),
|
||||
size(static_cast<mutable_buffer &>(*this)),
|
||||
e.what(),
|
||||
};
|
||||
}
|
||||
|
||||
ircd::fs::map &
|
||||
ircd::fs::map::operator=(map &&other)
|
||||
noexcept
|
||||
{
|
||||
auto &ours
|
||||
{
|
||||
static_cast<mutable_buffer &>(*this)
|
||||
};
|
||||
|
||||
auto &theirs
|
||||
{
|
||||
static_cast<mutable_buffer &>(other)
|
||||
};
|
||||
|
||||
this->~map();
|
||||
ours = theirs;
|
||||
theirs = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint
|
||||
ircd::fs::prot(const map::opts &opts)
|
||||
{
|
||||
uint ret
|
||||
{
|
||||
PROT_NONE
|
||||
};
|
||||
|
||||
if(opts.mode & std::ios::in)
|
||||
ret |= PROT_READ;
|
||||
|
||||
if(opts.mode & std::ios::out)
|
||||
ret |= PROT_WRITE;
|
||||
|
||||
assert(!opts.execute);
|
||||
if((false) && opts.execute)
|
||||
ret |= PROT_EXEC;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint
|
||||
ircd::fs::flags(const map::opts &opts)
|
||||
{
|
||||
uint ret
|
||||
{
|
||||
0
|
||||
};
|
||||
|
||||
if(opts.shared)
|
||||
ret |= MAP_SHARED;
|
||||
else
|
||||
ret |= MAP_PRIVATE;
|
||||
|
||||
#if defined(MAP_NONBLOCK)
|
||||
if(!opts.blocking)
|
||||
ret |= MAP_NONBLOCK;
|
||||
#endif
|
||||
|
||||
#if defined(MAP_POPULATE)
|
||||
if(opts.populate)
|
||||
ret |= MAP_POPULATE;
|
||||
#endif
|
||||
|
||||
#if defined(MAP_NORESERVE)
|
||||
if(!opts.reserve)
|
||||
ret |= MAP_NORESERVE;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// fs/fd.h
|
||||
|
|
Loading…
Reference in a new issue