From 9fd3b968fc6c3061e24a0a6ae12500c80bbefa24 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Fri, 18 Jan 2019 22:41:52 -0500 Subject: [PATCH] make ioctl on directories use open policy --- README.md | 2 +- man/mergerfs.1 | 8 +-- src/ioctl.cpp | 159 +++++++++++++++++++++++++------------------------ 3 files changed, 84 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index b3b318a6..4af3b74a 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ When using policies which are based on a branch's available space the base path | search | access, getattr, getxattr, ioctl, listxattr, open, readlink | | N/A | fallocate, fgetattr, fsync, ftruncate, ioctl, read, readdir, release, statfs, write | -Due to FUSE limitations **ioctl** behaves differently if its acting on a directory. It'll use the **getattr** policy to find and open the directory before issuing the **ioctl**. In other cases where something may be searched (to confirm a directory exists across all source mounts) **getattr** will also be used. +In cases where something may be searched (to confirm a directory exists across all source mounts) **getattr** will be used. #### Path Preservation diff --git a/man/mergerfs.1 b/man/mergerfs.1 index 2cbdec92..dc8669f5 100644 --- a/man/mergerfs.1 +++ b/man/mergerfs.1 @@ -426,12 +426,8 @@ statfs, write T} .TE .PP -Due to FUSE limitations \f[B]ioctl\f[] behaves differently if its acting -on a directory. -It\[aq]ll use the \f[B]getattr\f[] policy to find and open the directory -before issuing the \f[B]ioctl\f[]. -In other cases where something may be searched (to confirm a directory -exists across all source mounts) \f[B]getattr\f[] will also be used. +In cases where something may be searched (to confirm a directory exists +across all source mounts) \f[B]getattr\f[] will be used. .SS Path Preservation .PP Policies, as described below, are of two basic types. diff --git a/src/ioctl.cpp b/src/ioctl.cpp index 0166029b..f33c25a3 100644 --- a/src/ioctl.cpp +++ b/src/ioctl.cpp @@ -14,13 +14,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - -#include -#include - -#include - #include "config.hpp" #include "dirinfo.hpp" #include "errno.hpp" @@ -32,33 +25,42 @@ #include "rwlock.hpp" #include "ugid.hpp" +#include + +#include +#include + +#include + using std::string; using std::vector; using namespace mergerfs; -static -int -_ioctl(const int fd, - const unsigned long cmd, - void *data) +namespace local { - int rv; + static + int + ioctl(const int fd_, + const unsigned long cmd_, + void *data_) + { + int rv; - rv = fs::ioctl(fd,cmd,data); + rv = fs::ioctl(fd_,cmd_,data_); - return ((rv == -1) ? -errno : rv); -} + return ((rv == -1) ? -errno : rv); + } -static -int -_ioctl_file(fuse_file_info *ffi, - const unsigned long cmd, - void *data) -{ - FileInfo *fi = reinterpret_cast(ffi->fh); + static + int + ioctl_file(fuse_file_info *ffi_, + const unsigned long cmd_, + void *data_) + { + FileInfo *fi = reinterpret_cast(ffi_->fh); - return _ioctl(fi->fd,cmd,data); -} + return local::ioctl(fi->fd,cmd_,data_); + } #ifdef FUSE_IOCTL_DIR @@ -66,77 +68,78 @@ _ioctl_file(fuse_file_info *ffi, #define O_NOATIME 0 #endif -static -int -_ioctl_dir_base(Policy::Func::Search searchFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const unsigned long cmd, - void *data) -{ - int fd; - int rv; - string fullpath; - vector basepaths; + static + int + ioctl_dir_base(Policy::Func::Search searchFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const unsigned long cmd_, + void *data_) + { + int fd; + int rv; + string fullpath; + vector basepaths; - rv = searchFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; + rv = searchFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; - fs::path::make(basepaths[0],fusepath,fullpath); + fs::path::make(basepaths[0],fusepath_,fullpath); - const int flags = O_RDONLY | O_NOATIME | O_NONBLOCK; - fd = fs::open(fullpath,flags); - if(fd == -1) - return -errno; + const int flags = O_RDONLY | O_NOATIME | O_NONBLOCK; + fd = fs::open(fullpath,flags); + if(fd == -1) + return -errno; - rv = _ioctl(fd,cmd,data); + rv = local::ioctl(fd,cmd_,data_); - fs::close(fd); + fs::close(fd); - return rv; -} + return rv; + } -static -int -_ioctl_dir(fuse_file_info *ffi, - const unsigned long cmd, - void *data) -{ - DirInfo *di = reinterpret_cast(ffi->fh); - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _ioctl_dir_base(config.getattr, - config.branches, - config.minfreespace, - di->fusepath.c_str(), - cmd, - data); -} + static + int + ioctl_dir(fuse_file_info *ffi_, + const unsigned long cmd_, + void *data_) + { + DirInfo *di = reinterpret_cast(ffi_->fh); + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return local::ioctl_dir_base(config.open, + config.branches, + config.minfreespace, + di->fusepath.c_str(), + cmd_, + data_); + } #endif +} namespace mergerfs { namespace fuse { int - ioctl(const char *fusepath, - int cmd, - void *arg, - fuse_file_info *ffi, - unsigned int flags, - void *data) + ioctl(const char *fusepath_, + int cmd_, + void *arg_, + fuse_file_info *ffi_, + unsigned int flags_, + void *data_) { #ifdef FUSE_IOCTL_DIR - if(flags & FUSE_IOCTL_DIR) - return ::_ioctl_dir(ffi,cmd,data); + if(flags_ & FUSE_IOCTL_DIR) + return local::ioctl_dir(ffi_,cmd_,data_); #endif - return ::_ioctl_file(ffi,cmd,data); + return local::ioctl_file(ffi_,cmd_,data_); } } }