From 61181e10015f502966472267aba23e3b09784aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Gubler?= Date: Fri, 10 Feb 2017 21:32:27 +0100 Subject: [PATCH 1/3] Bad fix to work with CIFS mount --- src/chown.cpp | 3 +++ src/fs_clonepath.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/chown.cpp b/src/chown.cpp index 2c15ffc1..e2df0259 100644 --- a/src/chown.cpp +++ b/src/chown.cpp @@ -96,6 +96,7 @@ namespace mergerfs uid_t uid, gid_t gid) { +/* const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); const ugid::Set ugid(fc->uid,fc->gid); @@ -107,6 +108,8 @@ namespace mergerfs fusepath, uid, gid); +*/ + return 0; } } } diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index c81e6432..dcfae384 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -97,8 +97,8 @@ namespace fs return -1; rv = fs::chown(topath,st); - if(rv == -1) - return -1; + //if(rv == -1) + // return -1; rv = fs::utime(topath,st); if(rv == -1) From 8ccda3efef9471bb35b2050489f3f14ad9a787e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Gubler?= Date: Sun, 12 Feb 2017 13:10:53 +0100 Subject: [PATCH 2/3] cifs config parameter added --- src/chown.cpp | 6 +++--- src/config.cpp | 1 + src/config.hpp | 1 + src/fs_clonepath.cpp | 13 ++++++++++--- src/option_parser.cpp | 4 ++++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/chown.cpp b/src/chown.cpp index e2df0259..2c5ff821 100644 --- a/src/chown.cpp +++ b/src/chown.cpp @@ -96,20 +96,20 @@ namespace mergerfs uid_t uid, gid_t gid) { -/* 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.srcmountslock); + if(config.cifs) + return 0; + return _chown(config.chown, config.srcmounts, config.minfreespace, fusepath, uid, gid); -*/ - return 0; } } } diff --git a/src/config.cpp b/src/config.cpp index e0c3de3e..4247beee 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -40,6 +40,7 @@ namespace mergerfs minfreespace(MINFREESPACE_DEFAULT), moveonenospc(false), direct_io(false), + cifs(false), POLICYINIT(access), POLICYINIT(chmod), POLICYINIT(chown), diff --git a/src/config.hpp b/src/config.hpp index 0ec36d04..5aaa025a 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -48,6 +48,7 @@ namespace mergerfs uint64_t minfreespace; bool moveonenospc; bool direct_io; + bool cifs; public: const Policy *policies[FuseFunc::Enum::END]; diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index dcfae384..6f3cb082 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -26,8 +26,10 @@ #include "fs_clonepath.hpp" #include "fs_path.hpp" #include "fs_xattr.hpp" +#include "config.hpp" using std::string; +using mergerfs::Config; static bool @@ -59,6 +61,9 @@ namespace fs string frompath; string dirname; + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + dirname = relative; fs::path::dirname(dirname); if(!dirname.empty()) @@ -96,9 +101,11 @@ namespace fs if((rv == -1) && !ignorable_error(errno)) return -1; - rv = fs::chown(topath,st); - //if(rv == -1) - // return -1; + if(!config.cifs) { + rv = fs::chown(topath,st); + if(rv == -1) + return -1; + } rv = fs::utime(topath,st); if(rv == -1) diff --git a/src/option_parser.cpp b/src/option_parser.cpp index 0ad72880..a586e326 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -143,6 +143,8 @@ parse_and_process_arg(Config &config, return (set_default_options(*outargs),0); else if(arg == "direct_io") return (config.direct_io=true,1); + else if(arg == "cifs") + return (config.cifs=true,0); return 1; } @@ -260,6 +262,8 @@ usage(void) " on write: default false\n" " -o func.=

set function to policy

\n" " -o category.=

set functions in category to

\n" + " -o cifs disable chown command execution as CIFS\n" + " don't support it\n" << std::endl; } From ea746a8094ea50dfe217eb0e39048bd0cc3cfaf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Gubler?= Date: Wed, 15 Feb 2017 20:54:29 +0100 Subject: [PATCH 3/3] autochown from master --- src/chown.cpp | 3 -- src/config.cpp | 1 - src/config.hpp | 1 - src/fs_base_chmod.hpp | 56 +++++++++++++++++++++++++++++++++++++ src/fs_base_chown.hpp | 65 +++++++++++++++++++++++++++++++++++++++++++ src/fs_clonefile.cpp | 4 +-- src/fs_clonepath.cpp | 15 +++------- src/option_parser.cpp | 4 --- 8 files changed, 127 insertions(+), 22 deletions(-) diff --git a/src/chown.cpp b/src/chown.cpp index 2c5ff821..2c15ffc1 100644 --- a/src/chown.cpp +++ b/src/chown.cpp @@ -101,9 +101,6 @@ namespace mergerfs const ugid::Set ugid(fc->uid,fc->gid); const rwlock::ReadGuard readlock(&config.srcmountslock); - if(config.cifs) - return 0; - return _chown(config.chown, config.srcmounts, config.minfreespace, diff --git a/src/config.cpp b/src/config.cpp index 4247beee..e0c3de3e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -40,7 +40,6 @@ namespace mergerfs minfreespace(MINFREESPACE_DEFAULT), moveonenospc(false), direct_io(false), - cifs(false), POLICYINIT(access), POLICYINIT(chmod), POLICYINIT(chown), diff --git a/src/config.hpp b/src/config.hpp index 5aaa025a..0ec36d04 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -48,7 +48,6 @@ namespace mergerfs uint64_t minfreespace; bool moveonenospc; bool direct_io; - bool cifs; public: const Policy *policies[FuseFunc::Enum::END]; diff --git a/src/fs_base_chmod.hpp b/src/fs_base_chmod.hpp index 39692d2f..2334def1 100644 --- a/src/fs_base_chmod.hpp +++ b/src/fs_base_chmod.hpp @@ -21,6 +21,10 @@ #include +#include "fs_base_stat.hpp" + +#define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) + namespace fs { static @@ -49,6 +53,58 @@ namespace fs { return ::fchmod(fd,st.st_mode); } + + static + inline + int + chmod_check_on_error(const std::string &path, + const mode_t mode) + { + int rv; + + rv = fs::chmod(path,mode); + if(rv == -1) + { + int error; + struct stat st; + + error = errno; + rv = fs::stat(path,st); + if(rv == -1) + return -1; + + if((st.st_mode & MODE_BITS) != (mode & MODE_BITS)) + return (errno=error,-1); + } + + return 0; + } + + static + inline + int + fchmod_check_on_error(const int fd, + const struct stat &st) + { + int rv; + + rv = fs::fchmod(fd,st); + if(rv == -1) + { + int error; + struct stat tmpst; + + error = errno; + rv = fs::fstat(fd,tmpst); + if(rv == -1) + return -1; + + if((st.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS)) + return (errno=error,-1); + } + + return 0; + } } #endif diff --git a/src/fs_base_chown.hpp b/src/fs_base_chown.hpp index 47b01741..a17fb60b 100644 --- a/src/fs_base_chown.hpp +++ b/src/fs_base_chown.hpp @@ -25,6 +25,8 @@ #include #include +#include "fs_base_stat.hpp" + namespace fs { static @@ -56,6 +58,15 @@ namespace fs return ::lchown(path.c_str(),uid,gid); } + static + inline + int + lchown(const std::string &path, + const struct stat &st) + { + return fs::lchown(path,st.st_uid,st.st_gid); + } + static inline int @@ -74,6 +85,60 @@ namespace fs { return fs::fchown(fd,st.st_uid,st.st_gid); } + + static + inline + int + lchown_check_on_error(const std::string &path, + const struct stat &st) + { + int rv; + + rv = fs::lchown(path,st); + if(rv == -1) + { + int error; + struct stat tmpst; + + error = errno; + rv = fs::lstat(path,tmpst); + if(rv == -1) + return -1; + + if((st.st_uid != tmpst.st_uid) || + (st.st_gid != tmpst.st_gid)) + return (errno=error,-1); + } + + return 0; + } + + static + inline + int + fchown_check_on_error(const int fd, + const struct stat &st) + { + int rv; + + rv = fs::fchown(fd,st); + if(rv == -1) + { + int error; + struct stat tmpst; + + error = errno; + rv = fs::fstat(fd,tmpst); + if(rv == -1) + return -1; + + if((st.st_uid != tmpst.st_uid) || + (st.st_gid != tmpst.st_gid)) + return (errno=error,-1); + } + + return 0; + } } #endif diff --git a/src/fs_clonefile.cpp b/src/fs_clonefile.cpp index a933536e..826790b9 100644 --- a/src/fs_clonefile.cpp +++ b/src/fs_clonefile.cpp @@ -176,11 +176,11 @@ namespace fs if((rv == -1) && !ignorable_error(errno)) return -1; - rv = fs::fchown(fdout,stin); + rv = fs::fchown_check_on_error(fdout,stin); if(rv == -1) return -1; - rv = fs::fchmod(fdout,stin); + rv = fs::fchmod_check_on_error(fdout,stin); if(rv == -1) return -1; diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index 6f3cb082..f4fb32ce 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -26,10 +26,8 @@ #include "fs_clonepath.hpp" #include "fs_path.hpp" #include "fs_xattr.hpp" -#include "config.hpp" using std::string; -using mergerfs::Config; static bool @@ -61,9 +59,6 @@ namespace fs string frompath; string dirname; - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - dirname = relative; fs::path::dirname(dirname); if(!dirname.empty()) @@ -87,7 +82,7 @@ namespace fs if(errno != EEXIST) return -1; - rv = fs::chmod(topath,st.st_mode); + rv = fs::chmod_check_on_error(topath,st.st_mode); if(rv == -1) return -1; } @@ -101,11 +96,9 @@ namespace fs if((rv == -1) && !ignorable_error(errno)) return -1; - if(!config.cifs) { - rv = fs::chown(topath,st); - if(rv == -1) - return -1; - } + rv = fs::lchown_check_on_error(topath,st); + if(rv == -1) + return -1; rv = fs::utime(topath,st); if(rv == -1) diff --git a/src/option_parser.cpp b/src/option_parser.cpp index a586e326..0ad72880 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -143,8 +143,6 @@ parse_and_process_arg(Config &config, return (set_default_options(*outargs),0); else if(arg == "direct_io") return (config.direct_io=true,1); - else if(arg == "cifs") - return (config.cifs=true,0); return 1; } @@ -262,8 +260,6 @@ usage(void) " on write: default false\n" " -o func.=

set function to policy

\n" " -o category.=

set functions in category to

\n" - " -o cifs disable chown command execution as CIFS\n" - " don't support it\n" << std::endl; }