mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-19 16:16:48 +00:00
fuse_getattr/statx: populate timeouts in fake_root and controlfile replies
The fake-root and control-file fast paths returned a synthetic stat without touching the timeout struct. Callers that took those paths ended up sending whatever the timeout struct happened to hold, which is uninitialized memory for the control-file path and whatever a prior call left there for the fake-root path. Kernel behavior is undefined when the timeout is garbage. Pass timeout_ into both helpers and set entry/attr from the configured cache values.
This commit is contained in:
committed by
trapexit
parent
0c17492c78
commit
f5d9a60b9d
+12
-4
@@ -73,7 +73,8 @@ _set_stat_if_leads_to_reg(const fs::path &path_,
|
||||
|
||||
static
|
||||
int
|
||||
_getattr_fake_root(struct stat *st_)
|
||||
_getattr_fake_root(struct stat *st_,
|
||||
fuse_timeouts_t *timeout_)
|
||||
{
|
||||
st_->st_dev = 0;
|
||||
st_->st_ino = 0;
|
||||
@@ -89,12 +90,16 @@ _getattr_fake_root(struct stat *st_)
|
||||
st_->st_mtime = 0;
|
||||
st_->st_ctime = 0;
|
||||
|
||||
timeout_->entry = cfg.cache_entry;
|
||||
timeout_->attr = cfg.cache_attr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_getattr_controlfile(struct stat *st_)
|
||||
_getattr_controlfile(struct stat *st_,
|
||||
fuse_timeouts_t *timeout_)
|
||||
{
|
||||
static const uid_t uid = ::getuid();
|
||||
static const gid_t gid = ::getgid();
|
||||
@@ -114,6 +119,9 @@ _getattr_controlfile(struct stat *st_)
|
||||
st_->st_mtime = now;
|
||||
st_->st_ctime = now;
|
||||
|
||||
timeout_->entry = cfg.cache_entry;
|
||||
timeout_->attr = cfg.cache_attr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -189,7 +197,7 @@ _getattr(const fs::path &fusepath_,
|
||||
cfg.symlinkify_timeout,
|
||||
cfg.follow_symlinks);
|
||||
if((rv < 0) && Config::is_rootdir(fusepath_))
|
||||
return ::_getattr_fake_root(st_);
|
||||
return ::_getattr_fake_root(st_,timeout_);
|
||||
|
||||
timeout_->entry = ((rv >= 0) ?
|
||||
cfg.cache_entry :
|
||||
@@ -225,7 +233,7 @@ FUSE::getattr(const fs::path &fusepath_,
|
||||
fuse_timeouts_t *timeout_)
|
||||
{
|
||||
if(Config::is_ctrl_file(fusepath_))
|
||||
return ::_getattr_controlfile(st_);
|
||||
return ::_getattr_controlfile(st_,timeout_);
|
||||
|
||||
return ::_getattr(fusepath_,st_,timeout_);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,8 @@ _set_stat_if_leads_to_reg(const fs::path &path_,
|
||||
|
||||
static
|
||||
int
|
||||
_statx_fake_root(struct fuse_statx *st_)
|
||||
_statx_fake_root(struct fuse_statx *st_,
|
||||
fuse_timeouts_t *timeout_)
|
||||
{
|
||||
st_->ino = 0;
|
||||
st_->mode = (S_IFDIR|S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
|
||||
@@ -88,12 +89,16 @@ _statx_fake_root(struct fuse_statx *st_)
|
||||
st_->mtime.tv_sec = 0;
|
||||
st_->ctime.tv_sec = 0;
|
||||
|
||||
timeout_->entry = cfg.cache_entry;
|
||||
timeout_->attr = cfg.cache_attr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_statx_controlfile(struct fuse_statx *st_)
|
||||
_statx_controlfile(struct fuse_statx *st_,
|
||||
fuse_timeouts_t *timeout_)
|
||||
{
|
||||
static const uid_t uid = ::getuid();
|
||||
static const gid_t gid = ::getgid();
|
||||
@@ -110,6 +115,9 @@ _statx_controlfile(struct fuse_statx *st_)
|
||||
st_->mtime.tv_sec = now;
|
||||
st_->ctime.tv_sec = now;
|
||||
|
||||
timeout_->entry = cfg.cache_entry;
|
||||
timeout_->attr = cfg.cache_attr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -192,7 +200,7 @@ _statx(const fs::path &fusepath_,
|
||||
cfg.symlinkify_timeout,
|
||||
cfg.follow_symlinks);
|
||||
if((rv < 0) && Config::is_rootdir(fusepath_))
|
||||
return ::_statx_fake_root(st_);
|
||||
return ::_statx_fake_root(st_,timeout_);
|
||||
|
||||
timeout_->entry = ((rv >= 0) ?
|
||||
cfg.cache_entry :
|
||||
@@ -237,7 +245,7 @@ FUSE::statx(const fuse_req_ctx_t *ctx_,
|
||||
const fs::path fusepath{fusepath_};
|
||||
|
||||
if(Config::is_ctrl_file(fusepath))
|
||||
return ::_statx_controlfile(st_);
|
||||
return ::_statx_controlfile(st_,timeout_);
|
||||
|
||||
return ::_statx(fusepath,
|
||||
flags_|AT_STATX_DONT_SYNC,
|
||||
|
||||
Reference in New Issue
Block a user