From d9ae6df01c2f733525aea6b51f88f9b370bb113e Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Mon, 3 Apr 2017 19:10:05 -0500 Subject: [PATCH 01/14] Get macOS working again. --- src/fs_base_utime.hpp | 10 ++++++++ src/fs_base_utime_generic.hpp | 46 +++++++++++++++++++++++++++++++---- src/fs_fallocate_osx.icpp | 3 ++- src/fs_inode.hpp | 3 ++- src/gidcache.cpp | 8 ++++++ tools/cppfind | 2 +- 6 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/fs_base_utime.hpp b/src/fs_base_utime.hpp index ae1b1afee..b57ae9f18 100644 --- a/src/fs_base_utime.hpp +++ b/src/fs_base_utime.hpp @@ -35,8 +35,13 @@ namespace fs { struct timespec times[2]; +#if __APPLE__ + times[0] = st.st_atimespec; + times[1] = st.st_mtimespec; +#else times[0] = st.st_atim; times[1] = st.st_mtim; +#endif return fs::utime(AT_FDCWD,path,times,0); } @@ -49,8 +54,13 @@ namespace fs { struct timespec times[2]; +#if __APPLE__ + times[0] = st.st_atimespec; + times[1] = st.st_mtimespec; +#else times[0] = st.st_atim; times[1] = st.st_mtim; +#endif return fs::utime(fd,times); } diff --git a/src/fs_base_utime_generic.hpp b/src/fs_base_utime_generic.hpp index eeea26ad9..13e2d8bd7 100644 --- a/src/fs_base_utime_generic.hpp +++ b/src/fs_base_utime_generic.hpp @@ -25,6 +25,10 @@ #include #include +#if __APPLE__ +#import /* MAXPATHLEN */ +#endif + #ifndef UTIME_NOW # define UTIME_NOW ((1l << 30) - 1l) #endif @@ -123,6 +127,7 @@ _set_utime_omit_to_current_value(const int dirfd, { int rv; struct stat st; + timespec *atime, *mtime; if(!_any_timespec_is_utime_omit(ts)) return 0; @@ -131,10 +136,18 @@ _set_utime_omit_to_current_value(const int dirfd, if(rv == -1) return -1; +#if __APPLE__ + atime = &st.st_atimespec; + mtime = &st.st_mtimespec; +#else + atime = &st.st_atim; + mtime = &st.st_mtim; +#endif + if(ts[0].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[0],&st.st_atim); + TIMESPEC_TO_TIMEVAL(&tv[0],atime); if(ts[1].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[1],&st.st_mtim); + TIMESPEC_TO_TIMEVAL(&tv[1],mtime); return 0; } @@ -148,6 +161,7 @@ _set_utime_omit_to_current_value(const int fd, { int rv; struct stat st; + timespec *atime, *mtime; if(!_any_timespec_is_utime_omit(ts)) return 0; @@ -156,10 +170,18 @@ _set_utime_omit_to_current_value(const int fd, if(rv == -1) return -1; +#if __APPLE__ + atime = &st.st_atimespec; + mtime = &st.st_mtimespec; +#else + atime = &st.st_atim; + mtime = &st.st_mtim; +#endif + if(ts[0].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[0],&st.st_atim); + TIMESPEC_TO_TIMEVAL(&tv[0],atime); if(ts[1].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[1],&st.st_mtim); + TIMESPEC_TO_TIMEVAL(&tv[1],mtime); return 0; } @@ -269,8 +291,22 @@ namespace fs if(rv == -1) return -1; - if((flags & AT_SYMLINK_NOFOLLOW) == 0) + if((flags & AT_SYMLINK_NOFOLLOW) == 0) { +#if __APPLE__ + + char fullpath[MAXPATHLEN]; + + if (fcntl(dirfd,F_GETPATH,fullpath) < 0) + return (errno=errno,-1); + + if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path.c_str(), MAXPATHLEN) > MAXPATHLEN) + return (errno=ENAMETOOLONG,-1); + + return ::utimes(fullpath,tvp); +#else return ::futimesat(dirfd,path.c_str(),tvp); +#endif + } if(_can_call_lutimes(dirfd,path,flags)) return ::lutimes(path.c_str(),tvp); diff --git a/src/fs_fallocate_osx.icpp b/src/fs_fallocate_osx.icpp index 70894142e..6d57f471c 100644 --- a/src/fs_fallocate_osx.icpp +++ b/src/fs_fallocate_osx.icpp @@ -18,6 +18,7 @@ #include "errno.hpp" #include "fs_fallocate.hpp" +#include "fs_base_ftruncate.hpp" namespace fs { @@ -52,6 +53,6 @@ namespace fs if(mode) return (errno=EOPNOTSUPP,-1); - return ::_fallocate_core(fd,offset,len); + return _fallocate_core(fd,offset,len); } } diff --git a/src/fs_inode.hpp b/src/fs_inode.hpp index b217305f4..7e07a7e0c 100644 --- a/src/fs_inode.hpp +++ b/src/fs_inode.hpp @@ -34,7 +34,8 @@ namespace fs void recompute(struct stat &st) { - st.st_ino |= (st.st_dev << 32); + uint64_t st_dev = st.st_dev; /* Mac OS has a 32-bit device ID */ + st.st_ino |= (st_dev << 32); } } } diff --git a/src/gidcache.cpp b/src/gidcache.cpp index 3bace59a4..0d5afbfb6 100644 --- a/src/gidcache.cpp +++ b/src/gidcache.cpp @@ -109,7 +109,15 @@ gid_t_cache::cache(const uid_t uid, rec->size = 0; ::getgrouplist(pwd.pw_name,gid,NULL,&rec->size); rec->size = std::min(MAXGIDS,rec->size); + + #if __APPLE__ + // OSX: getgrouplist(const char *name, int basegid, int *groups, int *ngroups) + rv = ::getgrouplist(pwd.pw_name,gid,(int*)rec->gids,&rec->size); +#else + // Linux: getgrouplist(const char *name, gid_t group, gid_t *groups int *ngroups) rv = ::getgrouplist(pwd.pw_name,gid,rec->gids,&rec->size); +#endif + if(rv == -1) { rec->gids[0] = gid; diff --git a/tools/cppfind b/tools/cppfind index bac073eb0..fa9dbad42 100755 --- a/tools/cppfind +++ b/tools/cppfind @@ -2,6 +2,6 @@ FUSE_CFLAGS="$(pkg-config --cflags fuse) -DFUSE_USE_VERSION=29" -echo "#include " | cpp ${FUSE_CFLAGS} | grep "${1}" > /dev/null +echo "#include " | cc -E ${FUSE_CFLAGS} - | grep "${1}" > /dev/null [ "$?" != "0" ]; echo $? From 1aea1d4e0d6be8d343222d6de0495eece4e8d754 Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Mon, 3 Apr 2017 19:11:11 -0500 Subject: [PATCH 02/14] Get xattrs working on macOS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the position argument isn’t carried all the way down resource forks won’t work properly (though it easily could be, that would change the internal API for everyone). --- Makefile | 2 +- src/fs_base_getxattr.hpp | 4 ++ src/fs_base_listxattr.hpp | 4 ++ src/fs_base_removexattr.hpp | 4 ++ src/fs_base_setxattr.hpp | 4 ++ src/fs_xattr.cpp | 90 +++++++++++++++++++++++++++++-------- src/getxattr.cpp | 9 ++++ src/getxattr.hpp | 10 +++++ src/setxattr.cpp | 10 +++++ src/setxattr.hpp | 10 +++++ src/xattr.hpp | 6 ++- 11 files changed, 133 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 895615e72..b3f945ad1 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ ifeq ($(PANDOC),"") $(warning "pandoc does not appear available: manpage won't be buildable") endif -XATTR_AVAILABLE = $(shell test ! -e /usr/include/attr/xattr.h; echo $$?) +XATTR_AVAILABLE = $(shell test ! -e /usr/include/attr/xattr.h -a ! -e /usr/include/sys/xattr.h; echo $$?) FUSE_AVAILABLE = $(shell ! pkg-config --exists fuse; echo $$?) diff --git a/src/fs_base_getxattr.hpp b/src/fs_base_getxattr.hpp index cc3e26da6..eb3deb171 100644 --- a/src/fs_base_getxattr.hpp +++ b/src/fs_base_getxattr.hpp @@ -35,7 +35,11 @@ namespace fs const size_t size) { #ifndef WITHOUT_XATTR +#if __APPLE__ + return ::getxattr(path.c_str(),attrname,value,size,0,XATTR_NOFOLLOW); +#else return ::lgetxattr(path.c_str(),attrname,value,size); +#endif /* __APPLE__ */ #else return (errno=ENOTSUP,-1); #endif diff --git a/src/fs_base_listxattr.hpp b/src/fs_base_listxattr.hpp index cbb2bbcec..4e6516798 100644 --- a/src/fs_base_listxattr.hpp +++ b/src/fs_base_listxattr.hpp @@ -34,7 +34,11 @@ namespace fs const size_t size) { #ifndef WITHOUT_XATTR +#if __APPLE__ + return ::listxattr(path.c_str(),list,size,XATTR_NOFOLLOW); +#else return ::llistxattr(path.c_str(),list,size); +#endif /* __APPLE__ */ #else return (errno=ENOTSUP,-1); #endif diff --git a/src/fs_base_removexattr.hpp b/src/fs_base_removexattr.hpp index 71b9c27a1..0dc6436ac 100644 --- a/src/fs_base_removexattr.hpp +++ b/src/fs_base_removexattr.hpp @@ -33,7 +33,11 @@ namespace fs const char *attrname) { #ifndef WITHOUT_XATTR +#if __APPLE__ + return ::removexattr(path.c_str(),attrname,XATTR_NOFOLLOW); +#else return ::lremovexattr(path.c_str(),attrname); +#endif /* __APPLE__ */ #else return (errno=ENOTSUP,-1); #endif diff --git a/src/fs_base_setxattr.hpp b/src/fs_base_setxattr.hpp index db7851e4e..bc9a3b82a 100644 --- a/src/fs_base_setxattr.hpp +++ b/src/fs_base_setxattr.hpp @@ -36,7 +36,11 @@ namespace fs const int flags) { #ifndef WITHOUT_XATTR +#if __APPLE__ + return ::setxattr(path.c_str(),name,value,size,0,flags); +#else return ::lsetxattr(path.c_str(),name,value,size,flags); +#endif /* __APPLE__ */ #else return (errno=ENOTSUP,-1); #endif diff --git a/src/fs_xattr.cpp b/src/fs_xattr.cpp index acd8fb050..f468ac9e2 100644 --- a/src/fs_xattr.cpp +++ b/src/fs_xattr.cpp @@ -36,6 +36,60 @@ using std::vector; using std::map; using std::istringstream; +/* + The Mac version of the get/set APIs includes a position arg to seek around the + resource fork; for all other uses, the value is 0. + + For the other APIs, there are no link-specific variants; rather the standard call + has a flags argument where XATTR_NOFOLLOW is specified to address the link itself. +*/ + +#if __APPLE__ + ssize_t + _flistxattr(int fd, char* namebuf, size_t size) + { + return ::flistxattr(fd, namebuf, size, 0); + } + + ssize_t + _llistxattr(const char* path, char* namebuf, size_t size) + { + return ::listxattr(path, namebuf, size, XATTR_NOFOLLOW); + } + + ssize_t + _fgetxattr(int fd, const char* name, char* value, size_t size) + { + return ::fgetxattr(fd, name, value, size, 0, 0); + } + + int + _lgetxattr(const char* path, const char* name, char* value, size_t size) + { + return ::getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); + } + + int + _fsetxattr(int fd, const char* name, const char* value, size_t size, int flags) + { + return ::fsetxattr(fd, name, value, size, 0, flags); + } + + int + _lsetxattr(const char* path, const char* name, const char* value, size_t size, int flags) + { + return ::setxattr(path, name, value, size, 0, flags && XATTR_NOFOLLOW); + } + +#else + #define _flistxattr ::flistxattr + #define _llistxattr ::llistxattr + #define _fgetxattr ::fgetxattr + #define _lgetxattr ::lgetxattr + #define _fsetxattr ::fsetxattr + #define _lsetxattr ::lsetxattr +#endif + namespace fs { namespace xattr @@ -51,13 +105,13 @@ namespace fs errno = ERANGE; while((rv == -1) && (errno == ERANGE)) { - rv = ::flistxattr(fd,NULL,0); + rv = _flistxattr(fd,NULL,0); if(rv <= 0) return rv; attrs.resize(rv); - rv = ::flistxattr(fd,&attrs[0],rv); + rv = _flistxattr(fd,&attrs[0],rv); } return rv; @@ -77,13 +131,13 @@ namespace fs errno = ERANGE; while((rv == -1) && (errno == ERANGE)) { - rv = ::llistxattr(path.c_str(),NULL,0); + rv = _llistxattr(path.c_str(),NULL,0); if(rv <= 0) return rv; attrs.resize(rv); - rv = ::llistxattr(path.c_str(),&attrs[0],rv); + rv = _llistxattr(path.c_str(),&attrs[0],rv); } return rv; @@ -166,13 +220,13 @@ namespace fs errno = ERANGE; while((rv == -1) && (errno == ERANGE)) { - rv = ::fgetxattr(fd,attr.c_str(),NULL,0); + rv = _fgetxattr(fd,attr.c_str(),NULL,0); if(rv <= 0) return rv; value.resize(rv); - rv = ::fgetxattr(fd,attr.c_str(),&value[0],rv); + rv = _fgetxattr(fd,attr.c_str(),&value[0],rv); } return rv; @@ -193,13 +247,13 @@ namespace fs errno = ERANGE; while((rv == -1) && (errno == ERANGE)) { - rv = ::lgetxattr(path.c_str(),attr.c_str(),NULL,0); + rv = _lgetxattr(path.c_str(),attr.c_str(),NULL,0); if(rv <= 0) return rv; value.resize(rv); - rv = ::lgetxattr(path.c_str(),attr.c_str(),&value[0],rv); + rv = _lgetxattr(path.c_str(),attr.c_str(),&value[0],rv); } return rv; @@ -301,11 +355,11 @@ namespace fs const int flags) { #ifndef WITHOUT_XATTR - return ::fsetxattr(fd, - key.c_str(), - value.data(), - value.size(), - flags); + return _fsetxattr(fd, + key.c_str(), + value.data(), + value.size(), + flags); #else return (errno=ENOTSUP,-1); #endif @@ -318,11 +372,11 @@ namespace fs const int flags) { #ifndef WITHOUT_XATTR - return ::lsetxattr(path.c_str(), - key.c_str(), - value.data(), - value.size(), - flags); + return _lsetxattr(path.c_str(), + key.c_str(), + value.data(), + value.size(), + flags); #else return (errno=ENOTSUP,-1); #endif diff --git a/src/getxattr.cpp b/src/getxattr.cpp index 2a4143eab..63536c4e8 100644 --- a/src/getxattr.cpp +++ b/src/getxattr.cpp @@ -302,11 +302,20 @@ namespace mergerfs { namespace fuse { +#if __APPLE__ + int + getxattr(const char *fusepath, + const char *attrname, + char *buf, + size_t count, + uint32_t position) +#else int getxattr(const char *fusepath, const char *attrname, char *buf, size_t count) +#endif { const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); diff --git a/src/getxattr.hpp b/src/getxattr.hpp index aefbf37ec..817b8559b 100644 --- a/src/getxattr.hpp +++ b/src/getxattr.hpp @@ -21,12 +21,22 @@ namespace mergerfs { namespace fuse { +#if __APPLE__ + int + getxattr(const char *fusepath, + const char *attrname, + char *buf, + size_t count, + uint32_t position); + } +#else int getxattr(const char *fusepath, const char *attrname, char *buf, size_t count); } +#endif } #endif diff --git a/src/setxattr.cpp b/src/setxattr.cpp index 1b7b8a561..22d1c0f34 100644 --- a/src/setxattr.cpp +++ b/src/setxattr.cpp @@ -353,12 +353,22 @@ namespace mergerfs { namespace fuse { +#if __APPLE__ + int + setxattr(const char *fusepath, + const char *attrname, + const char *attrval, + size_t attrvalsize, + int flags, + uint32_t position) +#else int setxattr(const char *fusepath, const char *attrname, const char *attrval, size_t attrvalsize, int flags) +#endif { const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); diff --git a/src/setxattr.hpp b/src/setxattr.hpp index a05e382a0..490df7396 100644 --- a/src/setxattr.hpp +++ b/src/setxattr.hpp @@ -21,12 +21,22 @@ namespace mergerfs { namespace fuse { +#if __APPLE__ + int + setxattr(const char *fusepath, + const char *attrname, + const char *attrval, + size_t attrvalsize, + int flags, + uint32_t position); +#else int setxattr(const char *fusepath, const char *attrname, const char *attrval, size_t attrvalsize, int flags); +#endif } } diff --git a/src/xattr.hpp b/src/xattr.hpp index 181fedf88..dd96ad32c 100644 --- a/src/xattr.hpp +++ b/src/xattr.hpp @@ -18,8 +18,12 @@ #define __XATTR_HPP__ #ifndef WITHOUT_XATTR +#if __APPLE__ +#include +#else #include -#endif +#endif /* __APPLE__ */ +#endif /* WITHOUT_XATTR */ #ifndef XATTR_CREATE # define XATTR_CREATE 0x1 From 39b777254984cc8ea83fd21dd8673420b1daa7e9 Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Tue, 4 Apr 2017 14:14:00 -0500 Subject: [PATCH 03/14] Fix issue with AT_FDCWD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OSX doesn’t like AT_FDCWD in it’s fcntl, but getcwd does the job. Also fixed an issue with absolute paths in the process. --- src/fs_base_utime_generic.hpp | 15 ++------------- src/futimesat.cpp | 5 +++++ src/futimesat.hpp | 9 +++++++++ src/futimesat_osx.icpp | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 src/futimesat.cpp create mode 100644 src/futimesat.hpp create mode 100644 src/futimesat_osx.icpp diff --git a/src/fs_base_utime_generic.hpp b/src/fs_base_utime_generic.hpp index 13e2d8bd7..bd4fd0d00 100644 --- a/src/fs_base_utime_generic.hpp +++ b/src/fs_base_utime_generic.hpp @@ -25,9 +25,7 @@ #include #include -#if __APPLE__ -#import /* MAXPATHLEN */ -#endif +#include "futimesat.hpp" /* futimesat replacement */ #ifndef UTIME_NOW # define UTIME_NOW ((1l << 30) - 1l) @@ -293,16 +291,7 @@ namespace fs if((flags & AT_SYMLINK_NOFOLLOW) == 0) { #if __APPLE__ - - char fullpath[MAXPATHLEN]; - - if (fcntl(dirfd,F_GETPATH,fullpath) < 0) - return (errno=errno,-1); - - if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path.c_str(), MAXPATHLEN) > MAXPATHLEN) - return (errno=ENAMETOOLONG,-1); - - return ::utimes(fullpath,tvp); + return _futimesat(dirfd,path.c_str(),tvp); #else return ::futimesat(dirfd,path.c_str(),tvp); #endif diff --git a/src/futimesat.cpp b/src/futimesat.cpp new file mode 100644 index 000000000..f99e606e9 --- /dev/null +++ b/src/futimesat.cpp @@ -0,0 +1,5 @@ +#include "futimesat.hpp" + +#ifdef __APPLE__ +#include "futimesat_osx.icpp" +#endif diff --git a/src/futimesat.hpp b/src/futimesat.hpp new file mode 100644 index 000000000..7fb3bfec5 --- /dev/null +++ b/src/futimesat.hpp @@ -0,0 +1,9 @@ +#ifndef __UTIMESAT_HPP__ +#define __UTIMESAT_HPP__ + +#if __APPLE__ +int +_futimesat(int dirfd, const char* path, struct timeval *tvp); +#endif + +#endif diff --git a/src/futimesat_osx.icpp b/src/futimesat_osx.icpp new file mode 100644 index 000000000..70c2986c9 --- /dev/null +++ b/src/futimesat_osx.icpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include /* MAXPATHLEN */ + + +int +_futimesat(int fd, const char* path, struct timeval *tvp) { + char fullpath[MAXPATHLEN]; + + // Handle absolute paths + if(path[0] == '/') { + return ::utimes(path,tvp); + } + + // OS X 10.12 (at least) has an issue with using AT_FDCWD in this specific call. + if (fd == AT_FDCWD) { + if (getcwd((char*)fullpath, MAXPATHLEN) == NULL) { + return -1; + } + } else { + if (fcntl(fd,F_GETPATH,fullpath) < 0) { + return -1; + } + } + + if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path, MAXPATHLEN) > MAXPATHLEN) { + return (errno=ENAMETOOLONG,-1); + } + + return ::utimes(fullpath,tvp);; +} From d1aec144a688644ffdbd0a9a75ce67f779ab84d0 Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Wed, 5 Apr 2017 12:10:54 -0500 Subject: [PATCH 04/14] Updating return/variable types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After running Clang’s analyzer on it there were quite a few places where there were mis-matched store sizes and signs. I updated them so that the underlying code more closely-matches the OS APIs and the type change happens at the FUSE connection. In this way, if FUSE ever updates the API to actually match the APIs of modern OSes, it’s a fix in one place. Also, I updated read/write to return the total read/write value the OS returned rather than blindly return the request count. --- src/fs.cpp | 4 +- src/fs_acl.cpp | 2 +- src/fs_base_getxattr.hpp | 2 +- src/fs_base_ioctl.hpp | 6 +-- src/fs_base_listxattr.hpp | 2 +- src/fs_base_readlink.hpp | 2 +- src/fs_clonefile.cpp | 45 +++++++++++----------- src/fs_inode.hpp | 6 ++- src/fs_movefile.cpp | 2 +- src/fs_xattr.cpp | 78 +++++++++++++++++++-------------------- src/getxattr.cpp | 28 +++++++------- src/gidcache.cpp | 16 +++++--- src/ioctl.cpp | 18 ++++----- src/listxattr.cpp | 12 +++--- src/mergerfs.cpp | 2 +- src/num.cpp | 2 +- src/read.cpp | 16 ++++---- src/readdir.cpp | 6 +-- src/readlink.cpp | 10 ++--- src/ugid_rwlock.hpp | 6 +-- src/write.cpp | 24 ++++++------ src/write_buf.cpp | 8 ++-- 22 files changed, 151 insertions(+), 146 deletions(-) diff --git a/src/fs.cpp b/src/fs.cpp index 31a2a521e..91d66e0cd 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -151,7 +151,7 @@ namespace fs return -1; dev = st.st_dev; - for(int i = 0, ei = srcmounts.size(); i != ei; i++) + for(size_t i = 0, ei = srcmounts.size(); i != ei; i++) { fs::path::make(&srcmounts[i],fusepath,fullpath); @@ -241,7 +241,7 @@ namespace fs if(spaceavail <= mfs) continue; - mfs = spaceavail; + mfs = (fsblkcnt_t)spaceavail; mfsbasepath = &basepaths[i]; } diff --git a/src/fs_acl.cpp b/src/fs_acl.cpp index 65b40bb25..d30ceecf3 100644 --- a/src/fs_acl.cpp +++ b/src/fs_acl.cpp @@ -30,7 +30,7 @@ namespace fs bool dir_has_defaults(const std::string &fullpath) { - int rv; + ssize_t rv; std::string dirpath = fullpath; fs::path::dirname(dirpath); diff --git a/src/fs_base_getxattr.hpp b/src/fs_base_getxattr.hpp index eb3deb171..b0ec163b5 100644 --- a/src/fs_base_getxattr.hpp +++ b/src/fs_base_getxattr.hpp @@ -28,7 +28,7 @@ namespace fs { static inline - int + ssize_t lgetxattr(const std::string &path, const char *attrname, void *value, diff --git a/src/fs_base_ioctl.hpp b/src/fs_base_ioctl.hpp index 9de639837..980378b64 100644 --- a/src/fs_base_ioctl.hpp +++ b/src/fs_base_ioctl.hpp @@ -26,9 +26,9 @@ namespace fs static inline int - ioctl(const int fd, - const int request, - void *data) + ioctl(const int fd, + const unsigned long request, + void *data) { return ::ioctl(fd,request,data); } diff --git a/src/fs_base_listxattr.hpp b/src/fs_base_listxattr.hpp index 4e6516798..1ce6020dc 100644 --- a/src/fs_base_listxattr.hpp +++ b/src/fs_base_listxattr.hpp @@ -28,7 +28,7 @@ namespace fs { static inline - int + ssize_t llistxattr(const std::string &path, char *list, const size_t size) diff --git a/src/fs_base_readlink.hpp b/src/fs_base_readlink.hpp index efe7fa478..b0c6cb92e 100644 --- a/src/fs_base_readlink.hpp +++ b/src/fs_base_readlink.hpp @@ -27,7 +27,7 @@ namespace fs { static inline - int + ssize_t readlink(const std::string &path, char *buf, const size_t bufsiz) diff --git a/src/fs_clonefile.cpp b/src/fs_clonefile.cpp index 826790b96..0def21662 100644 --- a/src/fs_clonefile.cpp +++ b/src/fs_clonefile.cpp @@ -48,13 +48,13 @@ using std::string; using std::vector; -int +ssize_t writen(const int fd, const char *buf, const size_t count) { size_t nleft; - ssize_t nwritten; + ssize_t nwritten = 0; nleft = count; while(nleft > 0) @@ -67,15 +67,15 @@ writen(const int fd, return -1; } - nleft -= nwritten; - buf += nwritten; + nleft -= (size_t)nwritten; + buf += (size_t)nwritten; } - return count; + return nwritten; } static -int +ssize_t copyfile_rw(const int fdin, const int fdout, const size_t count, @@ -83,8 +83,8 @@ copyfile_rw(const int fdin, { ssize_t nr; ssize_t nw; - ssize_t bufsize; - size_t totalwritten; + size_t bufsize; + ssize_t totalwritten; vector buf; bufsize = (blocksize * 16); @@ -93,7 +93,7 @@ copyfile_rw(const int fdin, fs::lseek(fdin,0,SEEK_SET); totalwritten = 0; - while(totalwritten < count) + while(totalwritten < (ssize_t)count) { nr = fs::read(fdin,&buf[0],bufsize); if(nr == -1) @@ -103,29 +103,30 @@ copyfile_rw(const int fdin, return -1; } - nw = writen(fdout,&buf[0],nr); + nw = writen(fdout,&buf[0],(size_t)nr); if(nw == -1) return -1; totalwritten += nw; } - return count; + return totalwritten; } static -int +ssize_t copydata(const int fdin, const int fdout, const size_t count, const size_t blocksize) { - int rv; + ssize_t rv; + off_t scount = (off_t)count; + + fs::fadvise(fdin,0,scount,POSIX_FADV_WILLNEED); + fs::fadvise(fdin,0,scount,POSIX_FADV_SEQUENTIAL); - fs::fadvise(fdin,0,count,POSIX_FADV_WILLNEED); - fs::fadvise(fdin,0,count,POSIX_FADV_SEQUENTIAL); - - fs::fallocate(fdout,0,0,count); + fs::fallocate(fdout,0,0,scount); rv = fs::sendfile(fdin,fdout,count); if((rv == -1) && ((errno == EINVAL) || (errno == ENOSYS))) @@ -153,18 +154,18 @@ ignorable_error(const int err) namespace fs { - int + ssize_t clonefile(const int fdin, const int fdout) { - int rv; + ssize_t rv; struct stat stin; rv = fs::fstat(fdin,stin); if(rv == -1) return -1; - rv = ::copydata(fdin,fdout,stin.st_size,stin.st_blksize); + rv = ::copydata(fdin,fdout,(size_t)stin.st_size,(size_t)stin.st_blksize); if(rv == -1) return -1; @@ -191,11 +192,11 @@ namespace fs return 0; } - int + ssize_t clonefile(const string &in, const string &out) { - int rv; + ssize_t rv; int fdin; int fdout; int error; diff --git a/src/fs_inode.hpp b/src/fs_inode.hpp index 7e07a7e0c..683a83f00 100644 --- a/src/fs_inode.hpp +++ b/src/fs_inode.hpp @@ -34,7 +34,11 @@ namespace fs void recompute(struct stat &st) { - uint64_t st_dev = st.st_dev; /* Mac OS has a 32-bit device ID */ + /* + Some OSes have 32-bit device IDs, so box this up first. + This does also presume a 64-bit inode value. + */ + uint64_t st_dev = (uint64_t)st.st_dev; st.st_ino |= (st_dev << 32); } } diff --git a/src/fs_movefile.cpp b/src/fs_movefile.cpp index 1ca1fa54a..b02715536 100644 --- a/src/fs_movefile.cpp +++ b/src/fs_movefile.cpp @@ -66,7 +66,7 @@ namespace fs return -1; fdin_st.st_size += additional_size; - rv = fs::mfs(basepaths,fdin_st.st_size,fdout_path); + rv = fs::mfs(basepaths,(uint64_t)fdin_st.st_size,fdout_path); if(rv == -1) return -1; diff --git a/src/fs_xattr.cpp b/src/fs_xattr.cpp index f468ac9e2..94d9c7648 100644 --- a/src/fs_xattr.cpp +++ b/src/fs_xattr.cpp @@ -63,19 +63,19 @@ using std::istringstream; return ::fgetxattr(fd, name, value, size, 0, 0); } - int + ssize_t _lgetxattr(const char* path, const char* name, char* value, size_t size) { return ::getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); } - int + ssize_t _fsetxattr(int fd, const char* name, const char* value, size_t size, int flags) { return ::fsetxattr(fd, name, value, size, 0, flags); } - int + ssize_t _lsetxattr(const char* path, const char* name, const char* value, size_t size, int flags) { return ::setxattr(path, name, value, size, 0, flags && XATTR_NOFOLLOW); @@ -94,7 +94,7 @@ namespace fs { namespace xattr { - int + ssize_t list(const int fd, vector &attrs) { @@ -109,9 +109,9 @@ namespace fs if(rv <= 0) return rv; - attrs.resize(rv); + attrs.resize((size_t)rv); - rv = _flistxattr(fd,&attrs[0],rv); + rv = _flistxattr(fd,&attrs[0],(size_t)rv); } return rv; @@ -120,7 +120,7 @@ namespace fs #endif } - int + ssize_t list(const string &path, vector &attrs) { @@ -135,9 +135,9 @@ namespace fs if(rv <= 0) return rv; - attrs.resize(rv); + attrs.resize((size_t)rv); - rv = _llistxattr(path.c_str(),&attrs[0],rv); + rv = _llistxattr(path.c_str(),&attrs[0],(size_t)rv); } return rv; @@ -146,11 +146,11 @@ namespace fs #endif } - int + ssize_t list(const int fd, vector &attrvector) { - int rv; + ssize_t rv; vector attrs; rv = list(fd,attrs); @@ -163,11 +163,11 @@ namespace fs return rv; } - int + ssize_t list(const string &path, vector &attrvector) { - int rv; + ssize_t rv; vector attrs; rv = list(path,attrs); @@ -180,11 +180,11 @@ namespace fs return rv; } - int + ssize_t list(const int fd, string &attrstr) { - int rv; + ssize_t rv; vector attrs; rv = list(fd,attrs); @@ -194,11 +194,11 @@ namespace fs return rv; } - int + ssize_t list(const string &path, string &attrstr) { - int rv; + ssize_t rv; vector attrs; rv = list(path,attrs); @@ -208,7 +208,7 @@ namespace fs return rv; } - int + ssize_t get(const int fd, const string &attr, vector &value) @@ -224,9 +224,9 @@ namespace fs if(rv <= 0) return rv; - value.resize(rv); + value.resize((size_t)rv); - rv = _fgetxattr(fd,attr.c_str(),&value[0],rv); + rv = _fgetxattr(fd,attr.c_str(),&value[0],(size_t)rv); } return rv; @@ -235,7 +235,7 @@ namespace fs #endif } - int + ssize_t get(const string &path, const string &attr, vector &value) @@ -251,9 +251,9 @@ namespace fs if(rv <= 0) return rv; - value.resize(rv); + value.resize((size_t)rv); - rv = _lgetxattr(path.c_str(),attr.c_str(),&value[0],rv); + rv = _lgetxattr(path.c_str(),attr.c_str(),&value[0],(size_t)rv); } return rv; @@ -262,12 +262,12 @@ namespace fs #endif } - int + ssize_t get(const int fd, const string &attr, string &value) { - int rv; + ssize_t rv; vector tmpvalue; rv = get(fd,attr,tmpvalue); @@ -277,12 +277,12 @@ namespace fs return rv; } - int + ssize_t get(const string &path, const string &attr, string &value) { - int rv; + ssize_t rv; vector tmpvalue; rv = get(path,attr,tmpvalue); @@ -292,11 +292,11 @@ namespace fs return rv; } - int + ssize_t get(const int fd, map &attrs) { - int rv; + ssize_t rv; string attrstr; rv = list(fd,attrstr); @@ -320,11 +320,11 @@ namespace fs return 0; } - int + ssize_t get(const string &path, map &attrs) { - int rv; + ssize_t rv; string attrstr; rv = list(path,attrstr); @@ -348,7 +348,7 @@ namespace fs return 0; } - int + ssize_t set(const int fd, const string &key, const string &value, @@ -365,7 +365,7 @@ namespace fs #endif } - int + ssize_t set(const string &path, const string &key, const string &value, @@ -382,11 +382,11 @@ namespace fs #endif } - int + ssize_t set(const int fd, const map &attrs) { - int rv; + ssize_t rv; for(map::const_iterator i = attrs.begin(), ei = attrs.end(); i != ei; ++i) @@ -414,11 +414,11 @@ namespace fs return fs::close(fd); } - int + ssize_t copy(const int fdin, const int fdout) { - int rv; + ssize_t rv; map attrs; rv = get(fdin,attrs); @@ -428,11 +428,11 @@ namespace fs return set(fdout,attrs); } - int + ssize_t copy(const string &from, const string &to) { - int rv; + ssize_t rv; map attrs; rv = get(from,attrs); diff --git a/src/getxattr.cpp b/src/getxattr.cpp index 63536c4e8..ce4b3c1c6 100644 --- a/src/getxattr.cpp +++ b/src/getxattr.cpp @@ -39,13 +39,13 @@ using std::set; using namespace mergerfs; static -int +ssize_t _lgetxattr(const string &path, const char *attrname, void *value, const size_t size) { - int rv; + ssize_t rv; rv = fs::lgetxattr(path,attrname,value,size); @@ -153,7 +153,7 @@ _getxattr_pid(string &attrvalue) } static -int +ssize_t _getxattr_controlfile(const Config &config, const char *attrname, char *buf, @@ -198,7 +198,7 @@ _getxattr_controlfile(const Config &config, len = attrvalue.size(); if(count == 0) - return len; + return (ssize_t)len; if(count < len) return -ERANGE; @@ -209,7 +209,7 @@ _getxattr_controlfile(const Config &config, } static -int +ssize_t _getxattr_from_string(char *destbuf, const size_t destbufsize, const string &src) @@ -217,18 +217,18 @@ _getxattr_from_string(char *destbuf, const size_t srcbufsize = src.size(); if(destbufsize == 0) - return srcbufsize; + return (ssize_t)srcbufsize; if(srcbufsize > destbufsize) return -ERANGE; memcpy(destbuf,src.data(),srcbufsize); - return srcbufsize; + return (ssize_t)srcbufsize; } static -int +ssize_t _getxattr_user_mergerfs_allpaths(const vector &srcmounts, const char *fusepath, char *buf, @@ -245,7 +245,7 @@ _getxattr_user_mergerfs_allpaths(const vector &srcmounts, } static -int +ssize_t _getxattr_user_mergerfs(const string &basepath, const char *fusepath, const string &fullpath, @@ -271,7 +271,7 @@ _getxattr_user_mergerfs(const string &basepath, } static -int +ssize_t _getxattr(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, @@ -280,7 +280,7 @@ _getxattr(Policy::Func::Search searchFunc, char *buf, const size_t count) { - int rv; + ssize_t rv; string fullpath; vector basepaths; @@ -303,14 +303,14 @@ namespace mergerfs namespace fuse { #if __APPLE__ - int + ssize_t getxattr(const char *fusepath, const char *attrname, char *buf, size_t count, uint32_t position) #else - int + ssize_t getxattr(const char *fusepath, const char *attrname, char *buf, @@ -331,7 +331,7 @@ namespace mergerfs return _getxattr(config.getxattr, config.srcmounts, - config.minfreespace, + (size_t)config.minfreespace, fusepath, attrname, buf, diff --git a/src/gidcache.cpp b/src/gidcache.cpp index 0d5afbfb6..995e0d6e7 100644 --- a/src/gidcache.cpp +++ b/src/gidcache.cpp @@ -66,8 +66,8 @@ gid_t_cache::lower_bound(gid_t_rec *begin, gid_t_rec *end, const uid_t uid) { - int step; - int count; + long step; + long count; gid_t_rec *iter; count = std::distance(begin,end); @@ -106,15 +106,19 @@ gid_t_cache::cache(const uid_t uid, rv = ::getpwuid_r(uid,&pwd,buf,sizeof(buf),&pwdrv); if(pwdrv != NULL && rv == 0) { + #if __APPLE__ + // OSX: getgrouplist(const char *name, int basegid, int *groups, int *ngroups) rec->size = 0; - ::getgrouplist(pwd.pw_name,gid,NULL,&rec->size); + ::getgrouplist(pwd.pw_name,(int)gid,NULL,&rec->size); rec->size = std::min(MAXGIDS,rec->size); - #if __APPLE__ - // OSX: getgrouplist(const char *name, int basegid, int *groups, int *ngroups) - rv = ::getgrouplist(pwd.pw_name,gid,(int*)rec->gids,&rec->size); + rv = ::getgrouplist(pwd.pw_name,(int)gid,(int*)rec->gids,&rec->size); #else // Linux: getgrouplist(const char *name, gid_t group, gid_t *groups int *ngroups) + rec->size = 0; + ::getgrouplist(pwd.pw_name,gid,NULL,&rec->size); + rec->size = std::min(MAXGIDS,rec->size); + rv = ::getgrouplist(pwd.pw_name,gid,rec->gids,&rec->size); #endif diff --git a/src/ioctl.cpp b/src/ioctl.cpp index c081bfc9a..c3aa89f12 100644 --- a/src/ioctl.cpp +++ b/src/ioctl.cpp @@ -37,9 +37,9 @@ using namespace mergerfs; static int -_ioctl(const int fd, - const int cmd, - void *data) +_ioctl(const int fd, + const unsigned long cmd, + void *data) { int rv; @@ -60,7 +60,7 @@ _ioctl_dir_base(Policy::Func::Search searchFunc, const vector &srcmounts, const uint64_t minfreespace, const char *fusepath, - const int cmd, + const unsigned long cmd, void *data) { int fd; @@ -88,9 +88,9 @@ _ioctl_dir_base(Policy::Func::Search searchFunc, static int -_ioctl_dir(const char *fusepath, - const int cmd, - void *data) +_ioctl_dir(const char *fusepath, + const unsigned long cmd, + void *data) { const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); @@ -121,13 +121,13 @@ namespace mergerfs #ifdef FUSE_IOCTL_DIR if(flags & FUSE_IOCTL_DIR) return _ioctl_dir(fusepath, - cmd, + (unsigned long)cmd, data); #endif FileInfo *fi = reinterpret_cast(ffi->fh); return _ioctl(fi->fd, - cmd, + (unsigned long)cmd, data); } } diff --git a/src/listxattr.cpp b/src/listxattr.cpp index b84be9efd..1c723f292 100644 --- a/src/listxattr.cpp +++ b/src/listxattr.cpp @@ -36,7 +36,7 @@ using std::vector; using namespace mergerfs; static -int +ssize_t _listxattr_controlfile(char *list, const size_t size) { @@ -59,18 +59,18 @@ _listxattr_controlfile(char *list, xattrs += ("user.mergerfs.func." + (std::string)*FuseFunc::fusefuncs[i] + '\0'); if(size == 0) - return xattrs.size(); + return (ssize_t)xattrs.size(); if(size < xattrs.size()) return -ERANGE; memcpy(list,xattrs.c_str(),xattrs.size()); - return xattrs.size(); + return (ssize_t)xattrs.size(); } static -int +ssize_t _listxattr(Policy::Func::Search searchFunc, const vector &srcmounts, const uint64_t minfreespace, @@ -78,7 +78,7 @@ _listxattr(Policy::Func::Search searchFunc, char *list, const size_t size) { - int rv; + ssize_t rv; string fullpath; vector basepaths; @@ -97,7 +97,7 @@ namespace mergerfs { namespace fuse { - int + ssize_t listxattr(const char *fusepath, char *list, size_t size) diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 5b65b7329..43aa2e624 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -142,7 +142,7 @@ namespace local { const int prio = -10; - std::srand(time(NULL)); + std::srand((unsigned int)time(NULL)); mergerfs::resources::reset_umask(); mergerfs::resources::maxout_rlimit_nofile(); mergerfs::resources::maxout_rlimit_fsize(); diff --git a/src/num.cpp b/src/num.cpp index 7f6a0ec4d..3e1894ca3 100644 --- a/src/num.cpp +++ b/src/num.cpp @@ -28,7 +28,7 @@ namespace num char *endptr; uint64_t tmp; - tmp = strtoll(str.c_str(),&endptr,10); + tmp = strtoul(str.c_str(),&endptr,10); switch(*endptr) { case 'k': diff --git a/src/read.cpp b/src/read.cpp index 80d08c09b..e3b8ea710 100644 --- a/src/read.cpp +++ b/src/read.cpp @@ -26,32 +26,30 @@ static inline -int +ssize_t _read(const int fd, void *buf, const size_t count, const off_t offset) { - int rv; + ssize_t rv; rv = fs::pread(fd,buf,count,offset); if(rv == -1) return -errno; - if(rv == 0) - return 0; - return count; + return rv; } static inline -int +ssize_t _read_direct_io(const int fd, void *buf, const size_t count, const off_t offset) { - int rv; + ssize_t rv; rv = fs::pread(fd,buf,count,offset); if(rv == -1) @@ -64,7 +62,7 @@ namespace mergerfs { namespace fuse { - int + ssize_t read(const char *fusepath, char *buf, size_t count, @@ -76,7 +74,7 @@ namespace mergerfs return _read(fi->fd,buf,count,offset); } - int + ssize_t read_direct_io(const char *fusepath, char *buf, size_t count, diff --git a/src/readdir.cpp b/src/readdir.cpp index 56d8e054b..c8d5d775e 100644 --- a/src/readdir.cpp +++ b/src/readdir.cpp @@ -50,7 +50,7 @@ _readdir(const vector &srcmounts, void *buf, const fuse_fill_dir_t filler) { - StrSet names; + StrSet names = StrSet(); string basepath; struct stat st = {0}; @@ -69,7 +69,7 @@ _readdir(const vector &srcmounts, dirfd = fs::dirfd(dh); st.st_dev = fs::devid(dirfd); if(st.st_dev == (dev_t)-1) - st.st_dev = i; + st.st_dev = (dev_t)i; rv = 0; for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh)) @@ -79,7 +79,7 @@ _readdir(const vector &srcmounts, continue; st.st_ino = de->d_ino; - st.st_mode = DTTOIF(de->d_type); + st.st_mode = (mode_t)DTTOIF(de->d_type); fs::inode::recompute(st); diff --git a/src/readlink.cpp b/src/readlink.cpp index b484b0524..e5b4f486b 100644 --- a/src/readlink.cpp +++ b/src/readlink.cpp @@ -28,13 +28,13 @@ using std::vector; using mergerfs::Policy; static -int +ssize_t _readlink_core(const string *basepath, const char *fusepath, char *buf, const size_t size) { - int rv; + ssize_t rv; string fullpath; fs::path::make(basepath,fusepath,fullpath); @@ -49,7 +49,7 @@ _readlink_core(const string *basepath, } static -int +ssize_t _readlink(Policy::Func::Search searchFunc, const vector &srcmounts, const uint64_t minfreespace, @@ -57,7 +57,7 @@ _readlink(Policy::Func::Search searchFunc, char *buf, const size_t size) { - int rv; + ssize_t rv; vector basepaths; rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); @@ -71,7 +71,7 @@ namespace mergerfs { namespace fuse { - int + ssize_t readlink(const char *fusepath, char *buf, size_t size) diff --git a/src/ugid_rwlock.hpp b/src/ugid_rwlock.hpp index 0c4dfd234..580a2ec82 100644 --- a/src/ugid_rwlock.hpp +++ b/src/ugid_rwlock.hpp @@ -48,13 +48,13 @@ namespace mergerfs if(currentuid != 0) { - ::seteuid(0); - ::setegid(0); + (void)::seteuid(0); + (void)::setegid(0); } if(newgid) { - ::setegid(newgid); + (void)::setegid(newgid); initgroups(newuid,newgid); } diff --git a/src/write.cpp b/src/write.cpp index 6d722b06a..be1f5deb1 100644 --- a/src/write.cpp +++ b/src/write.cpp @@ -26,7 +26,7 @@ using namespace mergerfs; -typedef int (*WriteFunc)(const int,const void*,const size_t,const off_t); +typedef ssize_t (*WriteFunc)(const int,const void*,const size_t,const off_t); static bool @@ -38,32 +38,30 @@ _out_of_space(const int error) static inline -int +ssize_t _write(const int fd, const void *buf, const size_t count, const off_t offset) { - int rv; + ssize_t rv; rv = fs::pwrite(fd,buf,count,offset); if(rv == -1) return -errno; - if(rv == 0) - return 0; - return count; + return rv; } static inline -int +ssize_t _write_direct_io(const int fd, const void *buf, const size_t count, const off_t offset) { - int rv; + ssize_t rv; rv = fs::pwrite(fd,buf,count,offset); if(rv == -1) @@ -81,7 +79,7 @@ namespace mergerfs { static inline - int + ssize_t write(WriteFunc func, const char *fusepath, const char *buf, @@ -89,11 +87,11 @@ namespace mergerfs const off_t offset, fuse_file_info *ffi) { - int rv; + ssize_t rv; FileInfo* fi = reinterpret_cast(ffi->fh); rv = func(fi->fd,buf,count,offset); - if(_out_of_space(-rv)) + if(_out_of_space((int)-rv)) { const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); @@ -114,7 +112,7 @@ namespace mergerfs return rv; } - int + ssize_t write(const char *fusepath, const char *buf, size_t count, @@ -124,7 +122,7 @@ namespace mergerfs return write(_write,fusepath,buf,count,offset,ffi); } - int + ssize_t write_direct_io(const char *fusepath, const char *buf, size_t count, diff --git a/src/write_buf.cpp b/src/write_buf.cpp index db2624369..44f08dff9 100644 --- a/src/write_buf.cpp +++ b/src/write_buf.cpp @@ -46,7 +46,7 @@ _out_of_space(const int error) } static -int +ssize_t _write_buf(const int fd, fuse_bufvec &src, const off_t offset) @@ -67,17 +67,17 @@ namespace mergerfs { namespace fuse { - int + ssize_t write_buf(const char *fusepath, fuse_bufvec *src, off_t offset, fuse_file_info *ffi) { - int rv; + ssize_t rv; FileInfo *fi = reinterpret_cast(ffi->fh); rv = _write_buf(fi->fd,*src,offset); - if(_out_of_space(-rv)) + if(_out_of_space((int)-rv)) { const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); From 6cfd4d5d7b5c5cbbf13c96a8980353dce88afcf3 Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Wed, 5 Apr 2017 14:04:15 -0500 Subject: [PATCH 05/14] Clean up some cpp logic for __APPLE__ --- src/fs_base_getxattr.hpp | 8 +++----- src/fs_base_listxattr.hpp | 8 +++----- src/fs_base_removexattr.hpp | 8 +++----- src/fs_base_setxattr.hpp | 8 +++----- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/fs_base_getxattr.hpp b/src/fs_base_getxattr.hpp index b0ec163b5..0a4b2f41b 100644 --- a/src/fs_base_getxattr.hpp +++ b/src/fs_base_getxattr.hpp @@ -34,14 +34,12 @@ namespace fs void *value, const size_t size) { -#ifndef WITHOUT_XATTR -#if __APPLE__ +#if WITHOUT_XATTR + return (errno=ENOTSUP,-1); +#elif __APPLE__ return ::getxattr(path.c_str(),attrname,value,size,0,XATTR_NOFOLLOW); #else return ::lgetxattr(path.c_str(),attrname,value,size); -#endif /* __APPLE__ */ -#else - return (errno=ENOTSUP,-1); #endif } } diff --git a/src/fs_base_listxattr.hpp b/src/fs_base_listxattr.hpp index 1ce6020dc..8de8518a3 100644 --- a/src/fs_base_listxattr.hpp +++ b/src/fs_base_listxattr.hpp @@ -33,14 +33,12 @@ namespace fs char *list, const size_t size) { -#ifndef WITHOUT_XATTR -#if __APPLE__ +#ifdef WITHOUT_XATTR + return (errno=ENOTSUP,-1); +#elif __APPLE__ return ::listxattr(path.c_str(),list,size,XATTR_NOFOLLOW); #else return ::llistxattr(path.c_str(),list,size); -#endif /* __APPLE__ */ -#else - return (errno=ENOTSUP,-1); #endif } } diff --git a/src/fs_base_removexattr.hpp b/src/fs_base_removexattr.hpp index 0dc6436ac..1513354d4 100644 --- a/src/fs_base_removexattr.hpp +++ b/src/fs_base_removexattr.hpp @@ -32,14 +32,12 @@ namespace fs lremovexattr(const std::string &path, const char *attrname) { -#ifndef WITHOUT_XATTR -#if __APPLE__ +#if WITHOUT_XATTR + return (errno=ENOTSUP,-1); +#elif __APPLE__ return ::removexattr(path.c_str(),attrname,XATTR_NOFOLLOW); #else return ::lremovexattr(path.c_str(),attrname); -#endif /* __APPLE__ */ -#else - return (errno=ENOTSUP,-1); #endif } } diff --git a/src/fs_base_setxattr.hpp b/src/fs_base_setxattr.hpp index bc9a3b82a..1ce65f2d8 100644 --- a/src/fs_base_setxattr.hpp +++ b/src/fs_base_setxattr.hpp @@ -35,14 +35,12 @@ namespace fs const size_t size, const int flags) { -#ifndef WITHOUT_XATTR -#if __APPLE__ +#if WITHOUT_XATTR + return (errno=ENOTSUP,-1); +#elif __APPLE__ return ::setxattr(path.c_str(),name,value,size,0,flags); #else return ::lsetxattr(path.c_str(),name,value,size,flags); -#endif /* __APPLE__ */ -#else - return (errno=ENOTSUP,-1); #endif } } From 59ece5fdb44bb95220ce64d582d2dbdab6cd669a Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Wed, 5 Apr 2017 15:08:39 -0500 Subject: [PATCH 06/14] Adding position arg to xattr APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finder copies are broken without this argument, even if it’s fixed to 0. Upside: it reduces the number of times we platform-check in the xattr code. --- src/fs_acl.cpp | 2 +- src/fs_base_getxattr.hpp | 5 +- src/fs_base_setxattr.hpp | 13 ++--- src/fs_xattr.cpp | 109 ++++++++++++++++++++++----------------- src/getxattr.cpp | 27 +++++----- src/getxattr.hpp | 11 ++-- src/setxattr.cpp | 23 +++++---- src/setxattr.hpp | 9 +--- 8 files changed, 106 insertions(+), 93 deletions(-) diff --git a/src/fs_acl.cpp b/src/fs_acl.cpp index d30ceecf3..81f906764 100644 --- a/src/fs_acl.cpp +++ b/src/fs_acl.cpp @@ -35,7 +35,7 @@ namespace fs fs::path::dirname(dirpath); - rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0); + rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0,0); return (rv != -1); } diff --git a/src/fs_base_getxattr.hpp b/src/fs_base_getxattr.hpp index 0a4b2f41b..2cc695129 100644 --- a/src/fs_base_getxattr.hpp +++ b/src/fs_base_getxattr.hpp @@ -32,12 +32,13 @@ namespace fs lgetxattr(const std::string &path, const char *attrname, void *value, - const size_t size) + const size_t size, + const u_int32_t position) { #if WITHOUT_XATTR return (errno=ENOTSUP,-1); #elif __APPLE__ - return ::getxattr(path.c_str(),attrname,value,size,0,XATTR_NOFOLLOW); + return ::getxattr(path.c_str(),attrname,value,size,position,XATTR_NOFOLLOW); #else return ::lgetxattr(path.c_str(),attrname,value,size); #endif diff --git a/src/fs_base_setxattr.hpp b/src/fs_base_setxattr.hpp index 1ce65f2d8..7a1e2b954 100644 --- a/src/fs_base_setxattr.hpp +++ b/src/fs_base_setxattr.hpp @@ -33,15 +33,16 @@ namespace fs const char *name, const void *value, const size_t size, - const int flags) + const int flags, + const u_int32_t position) { -#if WITHOUT_XATTR + #if WITHOUT_XATTR return (errno=ENOTSUP,-1); -#elif __APPLE__ - return ::setxattr(path.c_str(),name,value,size,0,flags); -#else + #elif __APPLE__ + return ::setxattr(path.c_str(),name,value,size,position,flags & XATTR_NOFOLLOW); + #else return ::lsetxattr(path.c_str(),name,value,size,flags); -#endif + #endif } } diff --git a/src/fs_xattr.cpp b/src/fs_xattr.cpp index 94d9c7648..ee1a44c88 100644 --- a/src/fs_xattr.cpp +++ b/src/fs_xattr.cpp @@ -44,51 +44,66 @@ using std::istringstream; has a flags argument where XATTR_NOFOLLOW is specified to address the link itself. */ +ssize_t +_flistxattr(int fd, char* namebuf, size_t size) +{ #if __APPLE__ - ssize_t - _flistxattr(int fd, char* namebuf, size_t size) - { - return ::flistxattr(fd, namebuf, size, 0); - } - - ssize_t - _llistxattr(const char* path, char* namebuf, size_t size) - { - return ::listxattr(path, namebuf, size, XATTR_NOFOLLOW); - } - - ssize_t - _fgetxattr(int fd, const char* name, char* value, size_t size) - { - return ::fgetxattr(fd, name, value, size, 0, 0); - } + return ::flistxattr(fd, namebuf, size, XATTR_SHOWCOMPRESSION); +#else + return ::flistxattr(fd, namebuf, size); +#endif +} - ssize_t - _lgetxattr(const char* path, const char* name, char* value, size_t size) - { - return ::getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); - } - - ssize_t - _fsetxattr(int fd, const char* name, const char* value, size_t size, int flags) - { - return ::fsetxattr(fd, name, value, size, 0, flags); - } +ssize_t +_llistxattr(const char* path, char* namebuf, size_t size) +{ +#if __APPLE__ + return ::listxattr(path, namebuf, size, XATTR_SHOWCOMPRESSION & XATTR_NOFOLLOW); +#else + return ::llistxattr(path, namebuf, size); +#endif +} - ssize_t - _lsetxattr(const char* path, const char* name, const char* value, size_t size, int flags) - { - return ::setxattr(path, name, value, size, 0, flags && XATTR_NOFOLLOW); - } - +ssize_t +_fgetxattr(int fd, const char* name, char* value, size_t size, u_int32_t position) +{ +#if __APPLE__ + return ::fgetxattr(fd, name, value, size, position, XATTR_SHOWCOMPRESSION); #else - #define _flistxattr ::flistxattr - #define _llistxattr ::llistxattr - #define _fgetxattr ::fgetxattr - #define _lgetxattr ::lgetxattr - #define _fsetxattr ::fsetxattr - #define _lsetxattr ::lsetxattr + return ::fgetxattr(fd, name, value, size); #endif +} + +ssize_t +_lgetxattr(const char* path, const char* name, char* value, size_t size, u_int32_t position) +{ +#if __APPLE__ + return ::getxattr(path, name, value, size, position, XATTR_SHOWCOMPRESSION & XATTR_NOFOLLOW); +#else + return ::lgetxattr(path, name, value, size); +#endif +} + +ssize_t +_fsetxattr(int fd, const char* name, const char* value, size_t size, int flags, u_int32_t position) +{ +#if __APPLE__ + return ::fsetxattr(fd, name, value, size, position, flags); +#else + return ::fsetxattr(fd, name, value, size, flags); +#endif +} + +ssize_t +_lsetxattr(const char* path, const char* name, const char* value, size_t size, int flags, u_int32_t position) +{ +#if __APPLE__ + return ::setxattr(path, name, value, size, position, flags & XATTR_NOFOLLOW); +#else + return ::lsetxattr(path, name, value, size, flags); +#endif +} + namespace fs { @@ -220,13 +235,14 @@ namespace fs errno = ERANGE; while((rv == -1) && (errno == ERANGE)) { - rv = _fgetxattr(fd,attr.c_str(),NULL,0); + rv = _fgetxattr(fd,attr.c_str(),NULL,0,0); + if(rv <= 0) return rv; value.resize((size_t)rv); - rv = _fgetxattr(fd,attr.c_str(),&value[0],(size_t)rv); + rv = _fgetxattr(fd,attr.c_str(),&value[0],(size_t)rv, 0); } return rv; @@ -247,13 +263,14 @@ namespace fs errno = ERANGE; while((rv == -1) && (errno == ERANGE)) { - rv = _lgetxattr(path.c_str(),attr.c_str(),NULL,0); + rv = _lgetxattr(path.c_str(),attr.c_str(),NULL,0, 0); + if(rv <= 0) return rv; value.resize((size_t)rv); - rv = _lgetxattr(path.c_str(),attr.c_str(),&value[0],(size_t)rv); + rv = _lgetxattr(path.c_str(),attr.c_str(),&value[0],(size_t)rv, 0); } return rv; @@ -359,7 +376,7 @@ namespace fs key.c_str(), value.data(), value.size(), - flags); + flags,0); #else return (errno=ENOTSUP,-1); #endif @@ -376,7 +393,7 @@ namespace fs key.c_str(), value.data(), value.size(), - flags); + flags,0); #else return (errno=ENOTSUP,-1); #endif diff --git a/src/getxattr.cpp b/src/getxattr.cpp index ce4b3c1c6..548ee0370 100644 --- a/src/getxattr.cpp +++ b/src/getxattr.cpp @@ -43,11 +43,12 @@ ssize_t _lgetxattr(const string &path, const char *attrname, void *value, - const size_t size) + const size_t size, + const u_int32_t position) { ssize_t rv; - rv = fs::lgetxattr(path,attrname,value,size); + rv = fs::lgetxattr(path,attrname,value,size,position); return ((rv == -1) ? -errno : rv); } @@ -278,7 +279,8 @@ _getxattr(Policy::Func::Search searchFunc, const char *fusepath, const char *attrname, char *buf, - const size_t count) + size_t count, + u_int32_t position) { ssize_t rv; string fullpath; @@ -293,30 +295,30 @@ _getxattr(Policy::Func::Search searchFunc, if(str::isprefix(attrname,"user.mergerfs.")) rv = _getxattr_user_mergerfs(*basepaths[0],fusepath,fullpath,srcmounts,attrname,buf,count); else - rv = _lgetxattr(fullpath,attrname,buf,count); + rv = _lgetxattr(fullpath,attrname,buf,count,position); return rv; } +/* The FUSE API is different for rthe *xattr APIs on Mac OS; it adds the position parameter. */ + namespace mergerfs { namespace fuse { -#if __APPLE__ ssize_t getxattr(const char *fusepath, const char *attrname, char *buf, +#if __APPLE__ size_t count, - uint32_t position) + u_int32_t position) + { #else - ssize_t - getxattr(const char *fusepath, - const char *attrname, - char *buf, size_t count) -#endif { + u_int32_t position = 0; +#endif const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); @@ -335,7 +337,8 @@ namespace mergerfs fusepath, attrname, buf, - count); + count, + position); } } } diff --git a/src/getxattr.hpp b/src/getxattr.hpp index 817b8559b..1244b1b41 100644 --- a/src/getxattr.hpp +++ b/src/getxattr.hpp @@ -21,22 +21,17 @@ namespace mergerfs { namespace fuse { -#if __APPLE__ int getxattr(const char *fusepath, const char *attrname, char *buf, +#if __APPLE__ size_t count, - uint32_t position); - } + u_int32_t position); #else - int - getxattr(const char *fusepath, - const char *attrname, - char *buf, size_t count); - } #endif + } } #endif diff --git a/src/setxattr.cpp b/src/setxattr.cpp index 22d1c0f34..0adc03977 100644 --- a/src/setxattr.cpp +++ b/src/setxattr.cpp @@ -294,6 +294,7 @@ _setxattr_loop_core(const string *basepath, const char *attrval, const size_t attrvalsize, const int flags, + const u_int32_t position, const int error) { int rv; @@ -301,7 +302,7 @@ _setxattr_loop_core(const string *basepath, fs::path::make(basepath,fusepath,fullpath); - rv = fs::lsetxattr(fullpath,attrname,attrval,attrvalsize,flags); + rv = fs::lsetxattr(fullpath,attrname,attrval,attrvalsize,flags,position); return error::calc(rv,error,errno); } @@ -313,6 +314,7 @@ _setxattr_loop(const vector &basepaths, const char *attrname, const char *attrval, const size_t attrvalsize, + const u_int32_t position, const int flags) { int error; @@ -321,7 +323,7 @@ _setxattr_loop(const vector &basepaths, for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { error = _setxattr_loop_core(basepaths[i],fusepath, - attrname,attrval,attrvalsize,flags, + attrname,attrval,attrvalsize,flags,position, error); } @@ -337,6 +339,7 @@ _setxattr(Policy::Func::Action actionFunc, const char *attrname, const char *attrval, const size_t attrvalsize, + const u_int32_t position, const int flags) { int rv; @@ -346,30 +349,27 @@ _setxattr(Policy::Func::Action actionFunc, if(rv == -1) return -errno; - return _setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,flags); + return _setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,position,flags); } namespace mergerfs { namespace fuse { -#if __APPLE__ int setxattr(const char *fusepath, const char *attrname, const char *attrval, size_t attrvalsize, +#ifdef __APPLE__ int flags, - uint32_t position) + u_int32_t position) + { #else - int - setxattr(const char *fusepath, - const char *attrname, - const char *attrval, - size_t attrvalsize, int flags) -#endif { + u_int32_t position = 0; +#endif const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); @@ -389,6 +389,7 @@ namespace mergerfs attrname, attrval, attrvalsize, + position, flags); } } diff --git a/src/setxattr.hpp b/src/setxattr.hpp index 490df7396..ed9b67106 100644 --- a/src/setxattr.hpp +++ b/src/setxattr.hpp @@ -21,20 +21,15 @@ namespace mergerfs { namespace fuse { -#if __APPLE__ int setxattr(const char *fusepath, const char *attrname, const char *attrval, size_t attrvalsize, +#if __APPLE__ int flags, - uint32_t position); + u_int32_t position); #else - int - setxattr(const char *fusepath, - const char *attrname, - const char *attrval, - size_t attrvalsize, int flags); #endif } From 3b0d3715a1336e21aa05ac37015fc94b8ccb5e3c Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 6 Apr 2017 10:02:07 -0400 Subject: [PATCH 07/14] abstract futimesat and getting of atime/mtime --- src/fs_base_futimesat.cpp | 23 +++++++++ src/fs_base_futimesat.hpp | 30 +++++++++++ src/fs_base_futimesat_generic.icpp | 31 +++++++++++ src/fs_base_futimesat_osx.icpp | 82 ++++++++++++++++++++++++++++++ src/fs_base_stat.hpp | 50 ++++++++++++++++++ src/fs_base_utime.hpp | 20 +++----- src/fs_base_utime_generic.hpp | 39 +++++--------- 7 files changed, 236 insertions(+), 39 deletions(-) create mode 100644 src/fs_base_futimesat.cpp create mode 100644 src/fs_base_futimesat.hpp create mode 100644 src/fs_base_futimesat_generic.icpp create mode 100644 src/fs_base_futimesat_osx.icpp diff --git a/src/fs_base_futimesat.cpp b/src/fs_base_futimesat.cpp new file mode 100644 index 000000000..c254f4b93 --- /dev/null +++ b/src/fs_base_futimesat.cpp @@ -0,0 +1,23 @@ +/* + ISC License + + Copyright (c) 2017, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#if __APPLE__ +# include "fs_base_futimesat_osx.icpp" +#else +# include "fs_base_futimesat_generic.icpp" +#endif diff --git a/src/fs_base_futimesat.hpp b/src/fs_base_futimesat.hpp new file mode 100644 index 000000000..20f0938a4 --- /dev/null +++ b/src/fs_base_futimesat.hpp @@ -0,0 +1,30 @@ +/* + ISC License + + Copyright (c) 2017, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef __FS_BASE_FUTIMESAT_HPP__ +#define __FS_BASE_FUTIMESAT_HPP__ + +namespace fs +{ + int + futimesat(const int dirfd, + const char *pathname, + const struct timeval times[2]); +} + +#endif diff --git a/src/fs_base_futimesat_generic.icpp b/src/fs_base_futimesat_generic.icpp new file mode 100644 index 000000000..bfcd5e57e --- /dev/null +++ b/src/fs_base_futimesat_generic.icpp @@ -0,0 +1,31 @@ +/* + ISC License + + Copyright (c) 2017, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include +#include + +namespace fs +{ + int + futimesat(const int dirfd, + const char *pathname, + const struct timeval times[2]) + { + return ::futimesat(dirfd,pathname,times); + } +} diff --git a/src/fs_base_futimesat_osx.icpp b/src/fs_base_futimesat_osx.icpp new file mode 100644 index 000000000..ab81453fa --- /dev/null +++ b/src/fs_base_futimesat_osx.icpp @@ -0,0 +1,82 @@ +/* + ISC License + + Copyright (c) 2017, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static +int +getpath(const int dirfd, + const char *path, + char *fullpath) +{ + int rv; + struct stat st; + + rv = ::fstat(dirfd,&st); + if(rv == -1) + return -1; + + if(!S_ISDIR(st.st_mode)) + return (errno=ENOTDIR,-1); + + rv = ::fcntl(dirfd,F_GETPATH,fullpath); + if(rv == -1) + return -1; + + rv = ::strlcat(fullpath,"/",MAXPATHLEN); + if(rv > MAXPATHLEN) + return (errno=ENAMETOOLONG,-1); + + rv = ::strlcat(fullpath,path,MAXPATHLEN); + if(rv > MAXPATHLEN) + return (errno=ENAMETOOLONG,-1); + + return 0; +} + +namespace fs +{ + int + futimesat(const int dirfd, + const char *path, + const struct timeval times[2]) + { + char fullpath[MAXPATHLEN]; + + if((dirfd == AT_FDCWD) || + ((path != NULL) && (path[0] == '/'))) + return ::utimes(path,times); + + if(dirfd < 0) + return (errno=EBADF,-1); + + rv = getpath(dirfd,path,fullpath); + if(rv == -1) + return -1; + + return ::utimes(fullpath,times); + } +} diff --git a/src/fs_base_stat.hpp b/src/fs_base_stat.hpp index e67d52673..696327392 100644 --- a/src/fs_base_stat.hpp +++ b/src/fs_base_stat.hpp @@ -62,6 +62,56 @@ namespace fs { return ::fstat(fd,&st); } + + static + inline + timespec * + stat_atime(struct stat &st) + { +#if __APPLE__ + return &st.st_atimespec; +#else + return &st.st_atim; +#endif + } + + static + inline + const + timespec * + stat_atime(const struct stat &st) + { +#if __APPLE__ + return &st.st_atimespec; +#else + return &st.st_atim; +#endif + } + + static + inline + timespec * + stat_mtime(struct stat &st) + { +#if __APPLE__ + return &st.st_mtimespec; +#else + return &st.st_mtim; +#endif + } + + static + inline + const + timespec * + stat_mtime(const struct stat &st) + { +#if __APPLE__ + return &st.st_mtimespec; +#else + return &st.st_mtim; +#endif + } } #endif diff --git a/src/fs_base_utime.hpp b/src/fs_base_utime.hpp index b57ae9f18..2def8d5c5 100644 --- a/src/fs_base_utime.hpp +++ b/src/fs_base_utime.hpp @@ -25,6 +25,8 @@ # include "fs_base_utime_generic.hpp" #endif +#include "fs_base_stat.hpp" + namespace fs { static @@ -35,13 +37,8 @@ namespace fs { struct timespec times[2]; -#if __APPLE__ - times[0] = st.st_atimespec; - times[1] = st.st_mtimespec; -#else - times[0] = st.st_atim; - times[1] = st.st_mtim; -#endif + times[0] = *fs::stat_atime(st); + times[1] = *fs::stat_mtime(st); return fs::utime(AT_FDCWD,path,times,0); } @@ -54,13 +51,8 @@ namespace fs { struct timespec times[2]; -#if __APPLE__ - times[0] = st.st_atimespec; - times[1] = st.st_mtimespec; -#else - times[0] = st.st_atim; - times[1] = st.st_mtim; -#endif + times[0] = *fs::stat_atime(st); + times[1] = *fs::stat_mtime(st); return fs::utime(fd,times); } diff --git a/src/fs_base_utime_generic.hpp b/src/fs_base_utime_generic.hpp index bd4fd0d00..b8acdca49 100644 --- a/src/fs_base_utime_generic.hpp +++ b/src/fs_base_utime_generic.hpp @@ -25,7 +25,8 @@ #include #include -#include "futimesat.hpp" /* futimesat replacement */ +#include "fs_base_futimesat.hpp" +#include "fs_base_stat.hpp" #ifndef UTIME_NOW # define UTIME_NOW ((1l << 30) - 1l) @@ -125,7 +126,8 @@ _set_utime_omit_to_current_value(const int dirfd, { int rv; struct stat st; - timespec *atime, *mtime; + timespec *atime; + timespec *mtime; if(!_any_timespec_is_utime_omit(ts)) return 0; @@ -134,14 +136,9 @@ _set_utime_omit_to_current_value(const int dirfd, if(rv == -1) return -1; -#if __APPLE__ - atime = &st.st_atimespec; - mtime = &st.st_mtimespec; -#else - atime = &st.st_atim; - mtime = &st.st_mtim; -#endif - + atime = fs::stat_atime(st); + mtime = fs::stat_mtime(st); + if(ts[0].tv_nsec == UTIME_OMIT) TIMESPEC_TO_TIMEVAL(&tv[0],atime); if(ts[1].tv_nsec == UTIME_OMIT) @@ -159,7 +156,8 @@ _set_utime_omit_to_current_value(const int fd, { int rv; struct stat st; - timespec *atime, *mtime; + timespec *atime; + timespec *mtime; if(!_any_timespec_is_utime_omit(ts)) return 0; @@ -168,13 +166,8 @@ _set_utime_omit_to_current_value(const int fd, if(rv == -1) return -1; -#if __APPLE__ - atime = &st.st_atimespec; - mtime = &st.st_mtimespec; -#else - atime = &st.st_atim; - mtime = &st.st_mtim; -#endif + atime = fs::stat_atime(st); + mtime = fs::stat_mtime(st); if(ts[0].tv_nsec == UTIME_OMIT) TIMESPEC_TO_TIMEVAL(&tv[0],atime); @@ -289,13 +282,9 @@ namespace fs if(rv == -1) return -1; - if((flags & AT_SYMLINK_NOFOLLOW) == 0) { -#if __APPLE__ - return _futimesat(dirfd,path.c_str(),tvp); -#else - return ::futimesat(dirfd,path.c_str(),tvp); -#endif - } + if((flags & AT_SYMLINK_NOFOLLOW) == 0) + return fs::futimesat(dirfd,path.c_str(),tvp); + if(_can_call_lutimes(dirfd,path,flags)) return ::lutimes(path.c_str(),tvp); From bca840450d50b19832db7e6843ed40a9de78c62e Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Thu, 6 Apr 2017 09:34:23 -0500 Subject: [PATCH 08/14] Fix some compile errors for Travis --- src/fs_base_futimesat_osx.icpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fs_base_futimesat_osx.icpp b/src/fs_base_futimesat_osx.icpp index ab81453fa..9907f5433 100644 --- a/src/fs_base_futimesat_osx.icpp +++ b/src/fs_base_futimesat_osx.icpp @@ -64,6 +64,7 @@ namespace fs const char *path, const struct timeval times[2]) { + int rv; char fullpath[MAXPATHLEN]; if((dirfd == AT_FDCWD) || From b0fb5187c46693182f598b92e1a9632cfdde28eb Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 6 Apr 2017 11:18:03 -0400 Subject: [PATCH 09/14] restructure osx fallocate --- src/fs_fallocate_osx.icpp | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/fs_fallocate_osx.icpp b/src/fs_fallocate_osx.icpp index 6d57f471c..c43a0821f 100644 --- a/src/fs_fallocate_osx.icpp +++ b/src/fs_fallocate_osx.icpp @@ -20,30 +20,30 @@ #include "fs_fallocate.hpp" #include "fs_base_ftruncate.hpp" -namespace fs +static +int +_fallocate_core(const int fd, + const off_t offset, + const off_t len) { - static - int - _fallocate_core(const int fd, - const off_t offset, - const off_t len) - { - int rv; - fstore_t store = {F_ALLOCATECONTIG,F_PEOFPOSMODE,offset,len,0}; + int rv; + fstore_t store = {F_ALLOCATECONTIG,F_PEOFPOSMODE,offset,len,0}; - rv = ::fcntl(fd,F_PREALLOCATE,&store); - if(rv == -1) - { - store.fst_flags = F_ALLOCATEALL; - rv = ::fcntl(fd,F_PREALLOCATE,&store); - } + rv = ::fcntl(fd,F_PREALLOCATE,&store); + if(rv == -1) + { + store.fst_flags = F_ALLOCATEALL; + rv = ::fcntl(fd,F_PREALLOCATE,&store); + } - if(rv == -1) - return rv; + if(rv == -1) + return rv; - return ::ftruncate(fd,(offset+len)); - } + return ::ftruncate(fd,(offset+len)); +} +namespace fs +{ int fallocate(const int fd, const int mode, @@ -53,6 +53,6 @@ namespace fs if(mode) return (errno=EOPNOTSUPP,-1); - return _fallocate_core(fd,offset,len); + return ::_fallocate_core(fd,offset,len); } } From 6a67a92130aece173b32a51dcf1753892b75fe9a Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 6 Apr 2017 11:55:52 -0400 Subject: [PATCH 10/14] tweak types --- src/fs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fs.cpp b/src/fs.cpp index 91d66e0cd..43c5fb917 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -223,7 +223,7 @@ namespace fs const uint64_t minfreespace, string &path) { - fsblkcnt_t mfs; + uint64_t mfs; const string *mfsbasepath; mfs = 0; @@ -241,7 +241,7 @@ namespace fs if(spaceavail <= mfs) continue; - mfs = (fsblkcnt_t)spaceavail; + mfs = spaceavail; mfsbasepath = &basepaths[i]; } From 3b2fa957f738c23f602e66d48e44848e9d85a034 Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Thu, 6 Apr 2017 11:40:07 -0500 Subject: [PATCH 11/14] Silencing an analyzer notice (strlcat returns the size of the string as a size_t) --- src/fs_base_futimesat_osx.icpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fs_base_futimesat_osx.icpp b/src/fs_base_futimesat_osx.icpp index 9907f5433..6c781e98a 100644 --- a/src/fs_base_futimesat_osx.icpp +++ b/src/fs_base_futimesat_osx.icpp @@ -46,11 +46,11 @@ getpath(const int dirfd, if(rv == -1) return -1; - rv = ::strlcat(fullpath,"/",MAXPATHLEN); + rv = (int)::strlcat(fullpath,"/",MAXPATHLEN); if(rv > MAXPATHLEN) return (errno=ENAMETOOLONG,-1); - rv = ::strlcat(fullpath,path,MAXPATHLEN); + rv = (int)::strlcat(fullpath,path,MAXPATHLEN); if(rv > MAXPATHLEN) return (errno=ENAMETOOLONG,-1); From 25fe57fc04a6884d70c4dd61f292b1700db33572 Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Thu, 6 Apr 2017 11:42:02 -0500 Subject: [PATCH 12/14] Removed stray xattr flag Clients should get the xattrs they actually asked for, after all. --- src/fs_xattr.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fs_xattr.cpp b/src/fs_xattr.cpp index ee1a44c88..b8dcbcbd9 100644 --- a/src/fs_xattr.cpp +++ b/src/fs_xattr.cpp @@ -48,7 +48,7 @@ ssize_t _flistxattr(int fd, char* namebuf, size_t size) { #if __APPLE__ - return ::flistxattr(fd, namebuf, size, XATTR_SHOWCOMPRESSION); + return ::flistxattr(fd, namebuf, size, 0); #else return ::flistxattr(fd, namebuf, size); #endif @@ -58,7 +58,7 @@ ssize_t _llistxattr(const char* path, char* namebuf, size_t size) { #if __APPLE__ - return ::listxattr(path, namebuf, size, XATTR_SHOWCOMPRESSION & XATTR_NOFOLLOW); + return ::listxattr(path, namebuf, size, XATTR_NOFOLLOW); #else return ::llistxattr(path, namebuf, size); #endif @@ -68,7 +68,7 @@ ssize_t _fgetxattr(int fd, const char* name, char* value, size_t size, u_int32_t position) { #if __APPLE__ - return ::fgetxattr(fd, name, value, size, position, XATTR_SHOWCOMPRESSION); + return ::fgetxattr(fd, name, value, size, position, 0); #else return ::fgetxattr(fd, name, value, size); #endif @@ -78,7 +78,7 @@ ssize_t _lgetxattr(const char* path, const char* name, char* value, size_t size, u_int32_t position) { #if __APPLE__ - return ::getxattr(path, name, value, size, position, XATTR_SHOWCOMPRESSION & XATTR_NOFOLLOW); + return ::getxattr(path, name, value, size, position, XATTR_NOFOLLOW); #else return ::lgetxattr(path, name, value, size); #endif From d0fa9efa5116200ed70805c5b77873c8b4cce647 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 6 Apr 2017 16:15:12 -0400 Subject: [PATCH 13/14] handle 32bit inode sizes --- src/fs_inode.hpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/fs_inode.hpp b/src/fs_inode.hpp index 683a83f00..fac1b814a 100644 --- a/src/fs_inode.hpp +++ b/src/fs_inode.hpp @@ -19,6 +19,7 @@ #ifndef __FS_INODE_HPP__ #define __FS_INODE_HPP__ +#include #include namespace fs @@ -34,12 +35,10 @@ namespace fs void recompute(struct stat &st) { - /* - Some OSes have 32-bit device IDs, so box this up first. - This does also presume a 64-bit inode value. - */ - uint64_t st_dev = (uint64_t)st.st_dev; - st.st_ino |= (st_dev << 32); + if(sizeof(st.st_ino) == 4) + st.st_ino |= ((uint32_t)st.st_dev << 16); + else + st.st_ino |= ((uint64_t)st.st_dev << 32); } } } From cf567f11ce73a5bba646967bc9d47373d8d9c3fa Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 6 Apr 2017 17:06:34 -0400 Subject: [PATCH 14/14] remove unnecessary futimesat abstraction --- src/futimesat.cpp | 5 ----- src/futimesat.hpp | 9 --------- src/futimesat_osx.icpp | 35 ----------------------------------- 3 files changed, 49 deletions(-) delete mode 100644 src/futimesat.cpp delete mode 100644 src/futimesat.hpp delete mode 100644 src/futimesat_osx.icpp diff --git a/src/futimesat.cpp b/src/futimesat.cpp deleted file mode 100644 index f99e606e9..000000000 --- a/src/futimesat.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "futimesat.hpp" - -#ifdef __APPLE__ -#include "futimesat_osx.icpp" -#endif diff --git a/src/futimesat.hpp b/src/futimesat.hpp deleted file mode 100644 index 7fb3bfec5..000000000 --- a/src/futimesat.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __UTIMESAT_HPP__ -#define __UTIMESAT_HPP__ - -#if __APPLE__ -int -_futimesat(int dirfd, const char* path, struct timeval *tvp); -#endif - -#endif diff --git a/src/futimesat_osx.icpp b/src/futimesat_osx.icpp deleted file mode 100644 index 70c2986c9..000000000 --- a/src/futimesat_osx.icpp +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include /* MAXPATHLEN */ - - -int -_futimesat(int fd, const char* path, struct timeval *tvp) { - char fullpath[MAXPATHLEN]; - - // Handle absolute paths - if(path[0] == '/') { - return ::utimes(path,tvp); - } - - // OS X 10.12 (at least) has an issue with using AT_FDCWD in this specific call. - if (fd == AT_FDCWD) { - if (getcwd((char*)fullpath, MAXPATHLEN) == NULL) { - return -1; - } - } else { - if (fcntl(fd,F_GETPATH,fullpath) < 0) { - return -1; - } - } - - if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path, MAXPATHLEN) > MAXPATHLEN) { - return (errno=ENAMETOOLONG,-1); - } - - return ::utimes(fullpath,tvp);; -}