From 59ece5fdb44bb95220ce64d582d2dbdab6cd669a Mon Sep 17 00:00:00 2001 From: Adam Knight Date: Wed, 5 Apr 2017 15:08:39 -0500 Subject: [PATCH] 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 }