mirror of
https://github.com/trapexit/mergerfs.git
synced 2024-11-22 11:02:35 +08:00
Add ability to set readahead of mergerfs and branches
This commit is contained in:
parent
6e845b337a
commit
486c5d3734
|
@ -211,6 +211,8 @@ These options are the same regardless of whether you use them with the
|
|||
* **rename-exdev=passthrough|rel-symlink|abs-symlink**: When a rename
|
||||
fails with EXDEV optionally move the file to a special directory and
|
||||
symlink to it.
|
||||
* **readahead=UINT**: Set readahead (in kilobytes) for mergerfs and
|
||||
branches if greater than 0. (default: 0)
|
||||
* **posix_acl=BOOL**: Enable POSIX ACL support (if supported by kernel
|
||||
and underlying filesystem). (default: false)
|
||||
* **async_read=BOOL**: Perform reads asynchronously. If disabled or
|
||||
|
@ -1528,8 +1530,7 @@ understand what behaviors it may impact
|
|||
* use `symlinkify` if your data is largely static and read-only
|
||||
* use tiered cache drives
|
||||
* use LVM and LVM cache to place a SSD in front of your HDDs
|
||||
* if `cache.files` is enabled increase readahead: `echo "1024" > /sys/class/bdi/0:$(stat -c%d /MOUNT)/read_ahead_kb`
|
||||
* increase readahead on all devices: `ls -1 /sys/class/bdi/*/read_ahead_kb | xargs -n1 -I{} sh -c "echo 1024 > {}"`
|
||||
* increase readahead: `readahead=1024`
|
||||
|
||||
If you come across a setting that significantly impacts performance
|
||||
please contact trapexit so he may investigate further. Please test
|
||||
|
|
|
@ -265,6 +265,10 @@ instead.
|
|||
rename fails with EXDEV optionally move the file to a special directory
|
||||
and symlink to it.
|
||||
.IP \[bu] 2
|
||||
\f[B]readahead=UINT\f[R]: Set readahead (in kilobytes) for mergerfs and
|
||||
branches if greater than 0.
|
||||
(default: 0)
|
||||
.IP \[bu] 2
|
||||
\f[B]posix_acl=BOOL\f[R]: Enable POSIX ACL support (if supported by
|
||||
kernel and underlying filesystem).
|
||||
(default: false)
|
||||
|
@ -1982,11 +1986,7 @@ use tiered cache drives
|
|||
.IP \[bu] 2
|
||||
use LVM and LVM cache to place a SSD in front of your HDDs
|
||||
.IP \[bu] 2
|
||||
if \f[C]cache.files\f[R] is enabled increase readahead:
|
||||
\f[C]echo \[dq]1024\[dq] > /sys/class/bdi/0:$(stat -c%d /MOUNT)/read_ahead_kb\f[R]
|
||||
.IP \[bu] 2
|
||||
increase readahead on all devices:
|
||||
\f[C]ls -1 /sys/class/bdi/*/read_ahead_kb | xargs -n1 -I{} sh -c \[dq]echo 1024 > {}\[dq]\f[R]
|
||||
increase readahead: \f[C]readahead=1024\f[R]
|
||||
.PP
|
||||
If you come across a setting that significantly impacts performance
|
||||
please contact trapexit so he may investigate further.
|
||||
|
|
|
@ -105,6 +105,7 @@ Config::Config()
|
|||
nullrw(false),
|
||||
pid(::getpid()),
|
||||
posix_acl(false),
|
||||
readahead(0),
|
||||
readdir(ReadDir::ENUM::POSIX),
|
||||
readdirplus(false),
|
||||
rename_exdev(RenameEXDEV::ENUM::PASSTHROUGH),
|
||||
|
@ -176,6 +177,7 @@ Config::Config()
|
|||
_map["nullrw"] = &nullrw;
|
||||
_map["pid"] = &pid;
|
||||
_map["posix_acl"] = &posix_acl;
|
||||
_map["readahead"] = &readahead;
|
||||
// _map["readdir"] = &readdir;
|
||||
_map["readdirplus"] = &readdirplus;
|
||||
_map["rename-exdev"] = &rename_exdev;
|
||||
|
|
|
@ -133,6 +133,7 @@ public:
|
|||
ConfigBOOL nullrw;
|
||||
ConfigUINT64 pid;
|
||||
ConfigBOOL posix_acl;
|
||||
ConfigUINT64 readahead;
|
||||
ReadDir readdir;
|
||||
ConfigBOOL readdirplus;
|
||||
RenameEXDEV rename_exdev;
|
||||
|
|
86
src/fs_readahead.cpp
Normal file
86
src/fs_readahead.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2023, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
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 appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "fs_readahead.hpp"
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "fs_lstat.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
namespace l
|
||||
{
|
||||
static
|
||||
std::string
|
||||
generate_readahead_sys_path(const std::uint64_t major_,
|
||||
const std::uint64_t minor_)
|
||||
{
|
||||
return fmt::format("/sys/class/bdi/{}:{}/read_ahead_kb",major_,minor_);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
fs::readahead(const std::uint64_t major_dev_,
|
||||
const std::uint64_t minor_dev_,
|
||||
const std::uint64_t size_in_kb_)
|
||||
{
|
||||
std::string syspath;
|
||||
std::ofstream ofs;
|
||||
|
||||
syspath = l::generate_readahead_sys_path(major_dev_,minor_dev_);
|
||||
|
||||
ofs.open(syspath);
|
||||
if(ofs)
|
||||
{
|
||||
ofs << fmt::format("{}\n",size_in_kb_);
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fs::readahead(const std::uint64_t dev_,
|
||||
const std::uint64_t size_in_kb_)
|
||||
{
|
||||
std::uint32_t major_dev;
|
||||
std::uint32_t minor_dev;
|
||||
|
||||
major_dev = major(dev_);
|
||||
minor_dev = minor(dev_);
|
||||
|
||||
return fs::readahead(major_dev,minor_dev,size_in_kb_);
|
||||
}
|
||||
|
||||
int
|
||||
fs::readahead(const std::string path_,
|
||||
const std::uint64_t size_in_kb_)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
|
||||
rv = fs::lstat(path_,&st);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return fs::readahead(st.st_dev,size_in_kb_);
|
||||
}
|
39
src/fs_readahead.hpp
Normal file
39
src/fs_readahead.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2023, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
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 appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace fs
|
||||
{
|
||||
int
|
||||
readahead(const std::uint64_t major_dev,
|
||||
const std::uint64_t minor_dev,
|
||||
const std::uint64_t size_in_kb);
|
||||
|
||||
int
|
||||
readahead(const std::uint64_t dev,
|
||||
const std::uint64_t size_in_kb);
|
||||
|
||||
int
|
||||
readahead(const std::string path,
|
||||
const std::uint64_t size_in_kb);
|
||||
}
|
|
@ -16,9 +16,15 @@
|
|||
|
||||
#include "config.hpp"
|
||||
#include "ugid.hpp"
|
||||
#include "fs_readahead.hpp"
|
||||
#include "syslog.hpp"
|
||||
|
||||
#include "fmt/core.h"
|
||||
|
||||
#include "fuse.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
|
||||
namespace l
|
||||
{
|
||||
|
@ -77,6 +83,49 @@ namespace l
|
|||
cfg_->fuse_msg_size = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
readahead(const std::string path_,
|
||||
const int readahead_)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = fs::readahead(path_,readahead_);
|
||||
if(rv == 0)
|
||||
syslog_info("%s - readahead set to %d",path_.c_str(),readahead_);
|
||||
else
|
||||
syslog_error("%s - unable to set readahead",path_.c_str());
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
set_readahead_on_mount_and_branches()
|
||||
{
|
||||
Config::Read cfg;
|
||||
Branches::CPtr branches;
|
||||
|
||||
if((uint64_t)cfg->readahead == 0)
|
||||
return;
|
||||
|
||||
l::readahead(cfg->mountpoint,cfg->readahead);
|
||||
|
||||
branches = cfg->branches;
|
||||
for(auto const &branch : *branches)
|
||||
l::readahead(branch.path,cfg->readahead);
|
||||
}
|
||||
|
||||
// Spawn a thread to do this because before init returns calls to
|
||||
// set the value will block leading to a deadlock. This is just
|
||||
// easier.
|
||||
static
|
||||
void
|
||||
spawn_thread_to_set_readahead()
|
||||
{
|
||||
std::thread readahead_thread(l::set_readahead_on_mount_and_branches);
|
||||
|
||||
readahead_thread.detach();
|
||||
}
|
||||
}
|
||||
|
||||
namespace FUSE
|
||||
|
@ -104,6 +153,8 @@ namespace FUSE
|
|||
conn_->want &= ~FUSE_CAP_POSIX_LOCKS;
|
||||
conn_->want &= ~FUSE_CAP_FLOCK_LOCKS;
|
||||
|
||||
l::spawn_thread_to_set_readahead();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "fs_readahead.hpp"
|
||||
#include "fs_wait_for_mount.hpp"
|
||||
#include "syslog.hpp"
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user