Add ability to proxy ioprio of client apps (#1534)
Some checks failed
CodeQL / Analyze (push) Has been cancelled
mkdocs / deploy (push) Has been cancelled

This commit is contained in:
trapexit 2025-09-26 12:36:56 -04:00 • committed by GitHub
parent 2f3e807e9d
commit 569a151da2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 217 additions and 1 deletions

View file

@ -119,6 +119,7 @@ Config::Config()
nullrw(false),
parallel_direct_writes(true),
posix_acl(false),
proxy_ioprio(false),
readahead(0),
readdir("seq"),
readdirplus(false),
@ -207,6 +208,7 @@ Config::Config()
_map["parallel-direct-writes"] = &parallel_direct_writes;
_map["pin-threads"] = &fuse_pin_threads;
_map["posix_acl"] = &posix_acl;
_map["proxy-ioprio"] = &proxy_ioprio;
_map["readahead"] = &readahead;
_map["readdirplus"] = &readdirplus;
_map["rename-exdev"] = &rename_exdev;

View file

@ -30,6 +30,7 @@
#include "config_pagesize.hpp"
#include "config_passthrough.hpp"
#include "config_pid.hpp"
#include "config_proxy_ioprio.hpp"
#include "config_rename_exdev.hpp"
#include "config_set.hpp"
#include "config_statfs.hpp"
@ -126,6 +127,7 @@ public:
ConfigBOOL parallel_direct_writes;
ConfigGetPid pid;
ConfigBOOL posix_acl;
ProxyIOPrio proxy_ioprio;
ConfigUINT64 readahead;
FUSE::ReadDir readdir;
ConfigBOOL readdirplus;

View file

@ -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;
}

View file

@ -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;
};

View file

@ -24,7 +24,7 @@ public:
operator=(int v_)
{
if(!_err.has_value())
_err = v_;
_err = ((v_ >= 0) ? 0 : v_);
else if(v_ >= 0)
_err = 0;

View file

@ -19,6 +19,7 @@
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_pread.hpp"
#include "ioprio.hpp"
#include "fuse.h"
@ -60,6 +61,7 @@ FUSE::read(const fuse_file_info_t *ffi_,
size_t size_,
off_t offset_)
{
ioprio::SetFrom iop(fuse_get_context()->pid);
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
if(fi->direct_io)

View file

@ -24,6 +24,7 @@
#include "fs_movefile_and_open.hpp"
#include "fs_pwrite.hpp"
#include "fs_pwriten.hpp"
#include "ioprio.hpp"
#include "fuse.h"
@ -187,6 +188,8 @@ FUSE::write(const fuse_file_info_t *ffi_,
size_t count_,
off_t offset_)
{
ioprio::SetFrom iop(fuse_get_context()->pid);
return ::_write(ffi_,buf_,count_,offset_);
}

73
src/ioprio.cpp Normal file
View file

@ -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);
}

20
src/ioprio.hpp Normal file
View file

@ -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);
};
};