Browse Source

Adding position arg to xattr APIs

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.
pull/384/head
Adam Knight 9 years ago
parent
commit
59ece5fdb4
  1. 2
      src/fs_acl.cpp
  2. 5
      src/fs_base_getxattr.hpp
  3. 13
      src/fs_base_setxattr.hpp
  4. 109
      src/fs_xattr.cpp
  5. 27
      src/getxattr.cpp
  6. 11
      src/getxattr.hpp
  7. 23
      src/setxattr.cpp
  8. 9
      src/setxattr.hpp

2
src/fs_acl.cpp

@ -35,7 +35,7 @@ namespace fs
fs::path::dirname(dirpath); 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); return (rv != -1);
} }

5
src/fs_base_getxattr.hpp

@ -32,12 +32,13 @@ namespace fs
lgetxattr(const std::string &path, lgetxattr(const std::string &path,
const char *attrname, const char *attrname,
void *value, void *value,
const size_t size)
const size_t size,
const u_int32_t position)
{ {
#if WITHOUT_XATTR #if WITHOUT_XATTR
return (errno=ENOTSUP,-1); return (errno=ENOTSUP,-1);
#elif __APPLE__ #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 #else
return ::lgetxattr(path.c_str(),attrname,value,size); return ::lgetxattr(path.c_str(),attrname,value,size);
#endif #endif

13
src/fs_base_setxattr.hpp

@ -33,15 +33,16 @@ namespace fs
const char *name, const char *name,
const void *value, const void *value,
const size_t size, 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); 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); return ::lsetxattr(path.c_str(),name,value,size,flags);
#endif
#endif
} }
} }

109
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. 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__ #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 #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 #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 namespace fs
{ {
@ -220,13 +235,14 @@ namespace fs
errno = ERANGE; errno = ERANGE;
while((rv == -1) && (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) if(rv <= 0)
return rv; return rv;
value.resize((size_t)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; return rv;
@ -247,13 +263,14 @@ namespace fs
errno = ERANGE; errno = ERANGE;
while((rv == -1) && (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) if(rv <= 0)
return rv; return rv;
value.resize((size_t)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; return rv;
@ -359,7 +376,7 @@ namespace fs
key.c_str(), key.c_str(),
value.data(), value.data(),
value.size(), value.size(),
flags);
flags,0);
#else #else
return (errno=ENOTSUP,-1); return (errno=ENOTSUP,-1);
#endif #endif
@ -376,7 +393,7 @@ namespace fs
key.c_str(), key.c_str(),
value.data(), value.data(),
value.size(), value.size(),
flags);
flags,0);
#else #else
return (errno=ENOTSUP,-1); return (errno=ENOTSUP,-1);
#endif #endif

27
src/getxattr.cpp

@ -43,11 +43,12 @@ ssize_t
_lgetxattr(const string &path, _lgetxattr(const string &path,
const char *attrname, const char *attrname,
void *value, void *value,
const size_t size)
const size_t size,
const u_int32_t position)
{ {
ssize_t rv; ssize_t rv;
rv = fs::lgetxattr(path,attrname,value,size);
rv = fs::lgetxattr(path,attrname,value,size,position);
return ((rv == -1) ? -errno : rv); return ((rv == -1) ? -errno : rv);
} }
@ -278,7 +279,8 @@ _getxattr(Policy::Func::Search searchFunc,
const char *fusepath, const char *fusepath,
const char *attrname, const char *attrname,
char *buf, char *buf,
const size_t count)
size_t count,
u_int32_t position)
{ {
ssize_t rv; ssize_t rv;
string fullpath; string fullpath;
@ -293,30 +295,30 @@ _getxattr(Policy::Func::Search searchFunc,
if(str::isprefix(attrname,"user.mergerfs.")) if(str::isprefix(attrname,"user.mergerfs."))
rv = _getxattr_user_mergerfs(*basepaths[0],fusepath,fullpath,srcmounts,attrname,buf,count); rv = _getxattr_user_mergerfs(*basepaths[0],fusepath,fullpath,srcmounts,attrname,buf,count);
else else
rv = _lgetxattr(fullpath,attrname,buf,count);
rv = _lgetxattr(fullpath,attrname,buf,count,position);
return rv; return rv;
} }
/* The FUSE API is different for rthe *xattr APIs on Mac OS; it adds the position parameter. */
namespace mergerfs namespace mergerfs
{ {
namespace fuse namespace fuse
{ {
#if __APPLE__
ssize_t ssize_t
getxattr(const char *fusepath, getxattr(const char *fusepath,
const char *attrname, const char *attrname,
char *buf, char *buf,
#if __APPLE__
size_t count, size_t count,
uint32_t position)
u_int32_t position)
{
#else #else
ssize_t
getxattr(const char *fusepath,
const char *attrname,
char *buf,
size_t count) size_t count)
#endif
{ {
u_int32_t position = 0;
#endif
const fuse_context *fc = fuse_get_context(); const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc); const Config &config = Config::get(fc);
@ -335,7 +337,8 @@ namespace mergerfs
fusepath, fusepath,
attrname, attrname,
buf, buf,
count);
count,
position);
} }
} }
} }

11
src/getxattr.hpp

@ -21,22 +21,17 @@ namespace mergerfs
{ {
namespace fuse namespace fuse
{ {
#if __APPLE__
int int
getxattr(const char *fusepath, getxattr(const char *fusepath,
const char *attrname, const char *attrname,
char *buf, char *buf,
#if __APPLE__
size_t count, size_t count,
uint32_t position);
}
u_int32_t position);
#else #else
int
getxattr(const char *fusepath,
const char *attrname,
char *buf,
size_t count); size_t count);
}
#endif #endif
}
} }
#endif #endif

23
src/setxattr.cpp

@ -294,6 +294,7 @@ _setxattr_loop_core(const string *basepath,
const char *attrval, const char *attrval,
const size_t attrvalsize, const size_t attrvalsize,
const int flags, const int flags,
const u_int32_t position,
const int error) const int error)
{ {
int rv; int rv;
@ -301,7 +302,7 @@ _setxattr_loop_core(const string *basepath,
fs::path::make(basepath,fusepath,fullpath); 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); return error::calc(rv,error,errno);
} }
@ -313,6 +314,7 @@ _setxattr_loop(const vector<const string*> &basepaths,
const char *attrname, const char *attrname,
const char *attrval, const char *attrval,
const size_t attrvalsize, const size_t attrvalsize,
const u_int32_t position,
const int flags) const int flags)
{ {
int error; int error;
@ -321,7 +323,7 @@ _setxattr_loop(const vector<const string*> &basepaths,
for(size_t i = 0, ei = basepaths.size(); i != ei; i++) for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{ {
error = _setxattr_loop_core(basepaths[i],fusepath, error = _setxattr_loop_core(basepaths[i],fusepath,
attrname,attrval,attrvalsize,flags,
attrname,attrval,attrvalsize,flags,position,
error); error);
} }
@ -337,6 +339,7 @@ _setxattr(Policy::Func::Action actionFunc,
const char *attrname, const char *attrname,
const char *attrval, const char *attrval,
const size_t attrvalsize, const size_t attrvalsize,
const u_int32_t position,
const int flags) const int flags)
{ {
int rv; int rv;
@ -346,30 +349,27 @@ _setxattr(Policy::Func::Action actionFunc,
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return _setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,flags);
return _setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,position,flags);
} }
namespace mergerfs namespace mergerfs
{ {
namespace fuse namespace fuse
{ {
#if __APPLE__
int int
setxattr(const char *fusepath, setxattr(const char *fusepath,
const char *attrname, const char *attrname,
const char *attrval, const char *attrval,
size_t attrvalsize, size_t attrvalsize,
#ifdef __APPLE__
int flags, int flags,
uint32_t position)
u_int32_t position)
{
#else #else
int
setxattr(const char *fusepath,
const char *attrname,
const char *attrval,
size_t attrvalsize,
int flags) int flags)
#endif
{ {
u_int32_t position = 0;
#endif
const fuse_context *fc = fuse_get_context(); const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc); const Config &config = Config::get(fc);
@ -389,6 +389,7 @@ namespace mergerfs
attrname, attrname,
attrval, attrval,
attrvalsize, attrvalsize,
position,
flags); flags);
} }
} }

9
src/setxattr.hpp

@ -21,20 +21,15 @@ namespace mergerfs
{ {
namespace fuse namespace fuse
{ {
#if __APPLE__
int int
setxattr(const char *fusepath, setxattr(const char *fusepath,
const char *attrname, const char *attrname,
const char *attrval, const char *attrval,
size_t attrvalsize, size_t attrvalsize,
#if __APPLE__
int flags, int flags,
uint32_t position);
u_int32_t position);
#else #else
int
setxattr(const char *fusepath,
const char *attrname,
const char *attrval,
size_t attrvalsize,
int flags); int flags);
#endif #endif
} }

Loading…
Cancel
Save