diff options
author | Noah Watkins <noahwatkins@gmail.com> | 2013-07-20 18:41:40 -0700 |
---|---|---|
committer | Noah Watkins <noahwatkins@gmail.com> | 2013-09-17 10:22:53 -0700 |
commit | 2b55b52024c1e71e2dc8b4fa67c89dc33a58f2eb (patch) | |
tree | 8acd5abf5e8099e384f7d76beaa00eb674e1ef98 | |
parent | 416183546e83fd8d1a8b501b68503fe2daf56938 (diff) | |
download | ceph-2b55b52024c1e71e2dc8b4fa67c89dc33a58f2eb.tar.gz |
fuse: support get/set xattr on OSX
On OSX, the fuse get/set xattr interfaces takes a positional argument
that specifies an offset within the xattr. According to the OSX docs
only the 'resource fork' extended attribute will make use of this
feature and that all other attributes should set this to zero. Ceph
doesn't currently support xattr offsets (at the API level at least).
Therefore Ceph will return ENOTSUP if a non-zero positional argument is
used.
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
-rw-r--r-- | src/client/fuse_ll.cc | 48 | ||||
-rw-r--r-- | src/rbd_fuse/rbd-fuse.c | 49 |
2 files changed, 88 insertions, 9 deletions
diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 6bf5ea3d34f..e7013cda83a 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -151,15 +151,35 @@ static void fuse_ll_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, // XATTRS -static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name, - const char *value, size_t size, int flags) +static void __fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name, + const char *value, size_t size, int flags, uint32_t position) { CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req); const struct fuse_ctx *ctx = fuse_req_ctx(req); + + if (position) { + fuse_reply_err(req, -ENOTSUP); + return; + } + int r = cfuse->client->ll_setxattr(cfuse->fino_vino(ino), name, value, size, flags, ctx->uid, ctx->gid); fuse_reply_err(req, -r); } +#ifdef __APPLE__ +static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name, + const char *value, size_t size, int flags, uint32_t position) +{ + __fuse_ll_setxattr(req, ino, name, value, size, flags, position); +} +#else +static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name, + const char *value, size_t size, int flags) +{ + __fuse_ll_setxattr(req, ino, name, value, size, flags, 0); +} +#endif + static void fuse_ll_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size) { CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req); @@ -174,11 +194,17 @@ static void fuse_ll_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size) fuse_reply_err(req, -r); } -static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, - size_t size) +static void __fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, + size_t size, uint32_t position) { CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req); const struct fuse_ctx *ctx = fuse_req_ctx(req); + + if (position) { + fuse_reply_err(req, -ENOTSUP); + return; + } + char buf[size]; int r = cfuse->client->ll_getxattr(cfuse->fino_vino(ino), name, buf, size, ctx->uid, ctx->gid); if (size == 0 && r >= 0) @@ -189,6 +215,20 @@ static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, fuse_reply_err(req, -r); } +#ifdef __APPLE__ +static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, + size_t size, uint32_t position) +{ + __fuse_ll_getxattr(req, ino, name, size, position); +} +#else +static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, + size_t size) +{ + __fuse_ll_getxattr(req, ino, name, size, 0); +} +#endif + static void fuse_ll_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name) { CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req); diff --git a/src/rbd_fuse/rbd-fuse.c b/src/rbd_fuse/rbd-fuse.c index eea6edb9eb8..2ae8c57e07e 100644 --- a/src/rbd_fuse/rbd-fuse.c +++ b/src/rbd_fuse/rbd-fuse.c @@ -549,14 +549,17 @@ struct rbdfuse_attr { { NULL } }; -int -rbdfs_setxattr(const char *path, const char *name, const char *value, - size_t size, int flags) +static int +__rbdfs_setxattr(const char *path, const char *name, const char *value, + size_t size, int flags, uint32_t position) { struct rbdfuse_attr *ap; if (strcmp(path, "/") != 0) return -EINVAL; + if (position) + return -ENOTSUP; + for (ap = attrs; ap->attrname != NULL; ap++) { if (strcmp(name, ap->attrname) == 0) { *ap->attrvalp = strtoull(value, NULL, 0); @@ -568,15 +571,35 @@ rbdfs_setxattr(const char *path, const char *name, const char *value, return -EINVAL; } +#ifdef __APPLE__ int -rbdfs_getxattr(const char *path, const char *name, char *value, - size_t size) +rbdfs_setxattr(const char *path, const char *name, const char *value, + size_t size, int flags, uint32_t position) +{ + return __rbdfs_setxattr(path, name, value, size, flags, position); +} +#else +int +rbdfs_setxattr(const char *path, const char *name, const char *value, + size_t size, int flags) +{ + return __rbdfs_setxattr(path, name, value, size, flags, 0); +} +#endif + + +static int +__rbdfs_getxattr(const char *path, const char *name, char *value, + size_t size, uint32_t position) { struct rbdfuse_attr *ap; char buf[128]; // allow gets on other files; ls likes to ask for things like // security.* + if (position) + return -ENOTSUP; + for (ap = attrs; ap->attrname != NULL; ap++) { if (strcmp(name, ap->attrname) == 0) { sprintf(buf, "%"PRIu64, *ap->attrvalp); @@ -589,6 +612,22 @@ rbdfs_getxattr(const char *path, const char *name, char *value, return 0; } +#ifdef __APPLE__ +int +rbdfs_getxattr(const char *path, const char *name, char *value, + size_t size, uint32_t position) +{ + return __rbdfs_getxattr(path, name, value, size, position); +} +#else +int +rbdfs_getxattr(const char *path, const char *name, char *value, + size_t size) +{ + return __rbdfs_getxattr(path, name, value, size, 0); +} +#endif + int rbdfs_listxattr(const char *path, char *list, size_t len) { |