mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 19:01:56 -04:00
new features: follow-symlinks, rename-exdev, link-exdev
* follow-symlinks: allows mergerfs to transparently follow symlinks * link-exdev: in the event a link returns EXDEV create a symlink instead * rename-exdev: in the event a rename returns EXDEV move the oldpath and create a symlink for the newpath
This commit is contained in:
parent
50daf84ec0
commit
8adebc9489
26 changed files with 6980 additions and 450 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#include "fs_inode.hpp"
|
||||
#include "fs_lstat.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_stat.hpp"
|
||||
#include "symlinkify.hpp"
|
||||
#include "ugid.hpp"
|
||||
|
||||
|
|
@ -31,6 +32,42 @@ using std::string;
|
|||
|
||||
namespace l
|
||||
{
|
||||
static
|
||||
void
|
||||
set_stat_if_leads_to_dir(const std::string &path_,
|
||||
struct stat *st_)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
|
||||
rv = fs::stat(path_,&st);
|
||||
if(rv == -1)
|
||||
return;
|
||||
|
||||
if(S_ISDIR(st.st_mode))
|
||||
*st_ = st;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
set_stat_if_leads_to_reg(const std::string &path_,
|
||||
struct stat *st_)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
|
||||
rv = fs::stat(path_,&st);
|
||||
if(rv == -1)
|
||||
return;
|
||||
|
||||
if(S_ISREG(st.st_mode))
|
||||
*st_ = st;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
getattr_controlfile(struct stat *st_)
|
||||
|
|
@ -63,7 +100,8 @@ namespace l
|
|||
const char *fusepath_,
|
||||
struct stat *st_,
|
||||
const bool symlinkify_,
|
||||
const time_t symlinkify_timeout_)
|
||||
const time_t symlinkify_timeout_,
|
||||
FollowSymlinks followsymlinks_)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
|
@ -75,7 +113,28 @@ namespace l
|
|||
|
||||
fullpath = fs::path::make(basepaths[0],fusepath_);
|
||||
|
||||
rv = fs::lstat(fullpath,st_);
|
||||
switch(followsymlinks_)
|
||||
{
|
||||
case FollowSymlinks::ENUM::NEVER:
|
||||
rv = fs::lstat(fullpath,st_);
|
||||
break;
|
||||
case FollowSymlinks::ENUM::DIRECTORY:
|
||||
rv = fs::lstat(fullpath,st_);
|
||||
if(S_ISLNK(st_->st_mode))
|
||||
l::set_stat_if_leads_to_dir(fullpath,st_);
|
||||
break;
|
||||
case FollowSymlinks::ENUM::REGULAR:
|
||||
rv = fs::lstat(fullpath,st_);
|
||||
if(S_ISLNK(st_->st_mode))
|
||||
l::set_stat_if_leads_to_reg(fullpath,st_);
|
||||
break;
|
||||
case FollowSymlinks::ENUM::ALL:
|
||||
rv = fs::stat(fullpath,st_);
|
||||
if(rv != 0)
|
||||
rv = fs::lstat(fullpath,st_);
|
||||
break;
|
||||
}
|
||||
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
|
|
@ -102,7 +161,8 @@ namespace l
|
|||
fusepath_,
|
||||
st_,
|
||||
cfg->symlinkify,
|
||||
cfg->symlinkify_timeout);
|
||||
cfg->symlinkify_timeout,
|
||||
cfg->follow_symlinks);
|
||||
|
||||
timeout_->entry = ((rv >= 0) ?
|
||||
cfg->cache_entry :
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue