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 ae1b1afe..b57ae9f1 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 eeea26ad..13e2d8bd 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 70894142..6d57f471 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 b217305f..7e07a7e0 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 3bace59a..0d5afbfb 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 bac073eb..fa9dbad4 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 895615e7..b3f945ad 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 cc3e26da..eb3deb17 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 cbb2bbce..4e651679 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 71b9c27a..0dc6436a 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 db7851e4..bc9a3b82 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 acd8fb05..f468ac9e 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 2a4143ea..63536c4e 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 aefbf37e..817b8559 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 1b7b8a56..22d1c0f3 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 a05e382a..490df739 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 181fedf8..dd96ad32 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 13e2d8bd..bd4fd0d0 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 00000000..f99e606e --- /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 00000000..7fb3bfec --- /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 00000000..70c2986c --- /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 31a2a521..91d66e0c 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 65b40bb2..d30ceecf 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 eb3deb17..b0ec163b 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 9de63983..980378b6 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 4e651679..1ce6020d 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 efe7fa47..b0c6cb92 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 826790b9..0def2166 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 7e07a7e0..683a83f0 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 1ca1fa54..b0271553 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 f468ac9e..94d9c764 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 63536c4e..ce4b3c1c 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 0d5afbfb..995e0d6e 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 c081bfc9..c3aa89f1 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 b84be9ef..1c723f29 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 5b65b732..43aa2e62 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 7f6a0ec4..3e1894ca 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 80d08c09..e3b8ea71 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 56d8e054..c8d5d775 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 b484b052..e5b4f486 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 0c4dfd23..580a2ec8 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 6d722b06..be1f5deb 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 db262436..44f08dff 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 b0ec163b..0a4b2f41 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 1ce6020d..8de8518a 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 0dc6436a..1513354d 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 bc9a3b82..1ce65f2d 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 d30ceecf..81f90676 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 0a4b2f41..2cc69512 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 1ce65f2d..7a1e2b95 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 94d9c764..ee1a44c8 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 ce4b3c1c..548ee037 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 817b8559..1244b1b4 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 22d1c0f3..0adc0397 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 490df739..ed9b6710 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 00000000..c254f4b9 --- /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 00000000..20f0938a --- /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 00000000..bfcd5e57 --- /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 00000000..ab81453f --- /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 e67d5267..69632739 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 b57ae9f1..2def8d5c 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 bd4fd0d0..b8acdca4 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 ab81453f..9907f543 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 6d57f471..c43a0821 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 91d66e0c..43c5fb91 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 9907f543..6c781e98 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 ee1a44c8..b8dcbcbd 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 683a83f0..fac1b814 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 f99e606e..00000000 --- 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 7fb3bfec..00000000 --- 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 70c2986c..00000000 --- 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);; -}