mirror of https://github.com/trapexit/mergerfs.git
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 217 additions and 1 deletions
-
12mkdocs/docs/config/func_readdir.md
-
2mkdocs/docs/config/options.md
-
53mkdocs/docs/config/proxy-ioprio.md
-
1mkdocs/mkdocs.yml
-
2src/config.cpp
-
2src/config.hpp
-
33src/config_proxy_ioprio.cpp
-
13src/config_proxy_ioprio.hpp
-
2src/error.hpp
-
2src/fuse_read.cpp
-
3src/fuse_write.cpp
-
73src/ioprio.cpp
-
20src/ioprio.hpp
@ -0,0 +1,53 @@ |
|||||
|
# proxy-ioprio |
||||
|
|
||||
|
* type: `BOOL` |
||||
|
* default: `false` |
||||
|
* example: `proxy-ioprio=true` |
||||
|
|
||||
|
In Linux certain process schedulers have the ability to |
||||
|
[prioritize](https://man7.org/linux/man-pages/man2/ioprio_set.2.html) |
||||
|
based on a per thread [IO |
||||
|
priority](https://www.kernel.org/doc/Documentation/block/ioprio.txt) |
||||
|
assigned to the software by users using tools such as |
||||
|
[ionice](https://man7.org/linux/man-pages/man1/ionice.1.html). Since |
||||
|
such details are not provided by the FUSE protocol, users may not use |
||||
|
schedulers which support IO priority, and the extra overhead to query |
||||
|
the priority and set it within mergerfs it does not by default attempt |
||||
|
to mirror/proxy the value. When enabled however, for all read and |
||||
|
write requests, mergerfs will query the priority of the requesting |
||||
|
process/thread and set the same value on the thread within mergerfs |
||||
|
making the read/write. |
||||
|
|
||||
|
This may be useful in situation where the system has high IO load or |
||||
|
processes are known to have varying priorities. See the [man |
||||
|
page](https://man7.org/linux/man-pages/man2/ioprio_set.2.html) for |
||||
|
specific details. |
||||
|
|
||||
|
Keep in mind that if no IO scheduler has been set for a thread then by |
||||
|
default the IO priority will match the CPU nice value which for |
||||
|
mergerfs is set by [scheduling-priority](options.md). [Nice |
||||
|
value](https://man7.org/linux/man-pages/man2/getpriority.2.html) |
||||
|
proxying may be added in a future release. |
||||
|
|
||||
|
|
||||
|
## Conflicts With Other Options |
||||
|
|
||||
|
If using [IO passthrough](passthrough.md) there is no reason to set |
||||
|
this value to `true`. However, since `passthrough` leads to mergerfs |
||||
|
IO calls being bypassed entirely will have no impact on performance or |
||||
|
behavior regardless. |
||||
|
|
||||
|
When using `passthrough` the IO priority of the client app would be |
||||
|
used directly given the IO is passed through. |
||||
|
|
||||
|
|
||||
|
## Supported Platforms |
||||
|
|
||||
|
Only Linux. This is not supported on FreeBSD. |
||||
|
|
||||
|
|
||||
|
## Performance Impact |
||||
|
|
||||
|
Despite the additional syscalls requires the impact appears |
||||
|
undetectable with larger buffer sizes. At very small buffer sizes |
||||
|
(such as 512 bytes) there is a noticable but small impact (~1.5%). |
@ -0,0 +1,33 @@ |
|||||
|
#include "config_proxy_ioprio.hpp"
|
||||
|
|
||||
|
#include "ioprio.hpp"
|
||||
|
#include "from_string.hpp"
|
||||
|
|
||||
|
|
||||
|
ProxyIOPrio::ProxyIOPrio(const bool b_) |
||||
|
{ |
||||
|
ioprio::enable(b_); |
||||
|
} |
||||
|
|
||||
|
std::string |
||||
|
ProxyIOPrio::to_string(void) const |
||||
|
{ |
||||
|
if(ioprio::enabled()) |
||||
|
return "true"; |
||||
|
return "false"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
ProxyIOPrio::from_string(const std::string_view s_) |
||||
|
{ |
||||
|
int rv; |
||||
|
bool enable; |
||||
|
|
||||
|
rv = str::from(s_,&enable); |
||||
|
if(rv) |
||||
|
return rv; |
||||
|
|
||||
|
ioprio::enable(enable); |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
class ProxyIOPrio : public ToFromString |
||||
|
{ |
||||
|
public: |
||||
|
ProxyIOPrio(const bool); |
||||
|
|
||||
|
public: |
||||
|
std::string to_string(void) const final; |
||||
|
int from_string(const std::string_view) final; |
||||
|
}; |
@ -0,0 +1,73 @@ |
|||||
|
#include "ioprio.hpp"
|
||||
|
|
||||
|
#ifdef __linux__
|
||||
|
# include <linux/ioprio.h>
|
||||
|
# include <sys/syscall.h>
|
||||
|
# include <unistd.h>
|
||||
|
# include <errno.h>
|
||||
|
#else
|
||||
|
#warning "ioprio not supported on this platform"
|
||||
|
#endif
|
||||
|
|
||||
|
thread_local int ioprio::SetFrom::thread_prio = -1; |
||||
|
bool _enabled = false; |
||||
|
|
||||
|
int |
||||
|
ioprio::get(const int which_, |
||||
|
const int who_) |
||||
|
{ |
||||
|
#ifdef SYS_ioprio_get
|
||||
|
int rv; |
||||
|
|
||||
|
rv = syscall(SYS_ioprio_get,which_,who_); |
||||
|
|
||||
|
return ((rv == -1) ? -errno : rv); |
||||
|
#else
|
||||
|
return -ENOSUP; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
ioprio::set(const int which_, |
||||
|
const int who_, |
||||
|
const int ioprio_) |
||||
|
{ |
||||
|
#ifdef SYS_ioprio_set
|
||||
|
int rv; |
||||
|
|
||||
|
rv = syscall(SYS_ioprio_set,which_,who_,ioprio_); |
||||
|
|
||||
|
return ((rv == -1) ? -errno : rv); |
||||
|
#else
|
||||
|
return -ENOSUP; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
void |
||||
|
ioprio::enable(const bool enable_) |
||||
|
{ |
||||
|
_enabled = enable_; |
||||
|
} |
||||
|
|
||||
|
bool |
||||
|
ioprio::enabled() |
||||
|
{ |
||||
|
return _enabled; |
||||
|
} |
||||
|
|
||||
|
ioprio::SetFrom::SetFrom(const pid_t pid_) |
||||
|
{ |
||||
|
int client_prio; |
||||
|
|
||||
|
if(!_enabled) |
||||
|
return; |
||||
|
|
||||
|
client_prio = ioprio::get(IOPRIO_WHO_PROCESS,pid_); |
||||
|
if(client_prio < 0) |
||||
|
return; |
||||
|
if(client_prio == thread_prio) |
||||
|
return; |
||||
|
|
||||
|
thread_prio = client_prio; |
||||
|
ioprio::set(IOPRIO_WHO_PROCESS,0,client_prio); |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include <sys/types.h>
|
||||
|
|
||||
|
|
||||
|
namespace ioprio |
||||
|
{ |
||||
|
void enable(const bool); |
||||
|
bool enabled(); |
||||
|
|
||||
|
int get(const int which, const int who); |
||||
|
int set(const int which, const int who, const int ioprio); |
||||
|
|
||||
|
struct SetFrom |
||||
|
{ |
||||
|
static thread_local int thread_prio; |
||||
|
|
||||
|
SetFrom(const pid_t pid); |
||||
|
}; |
||||
|
}; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue