@@ -269,34 +269,48 @@ err_out:
return ret;
}
-static int local_set_xattr(const char *path, FsCred *credp)
+static int local_do_setxattr(int fd, const char *path,
+ const char *name, void *value, size_t size)
+{
+ if (path) {
+ return setxattr(path, name, value, size, 0);
+ } else {
+ return fsetxattr(fd, name, value, size, 0);
+ }
+}
+
+static int local_set_xattr(int fd, const char *path, FsCred *credp)
{
int err;
if (credp->fc_uid != -1) {
uint32_t tmp_uid = cpu_to_le32(credp->fc_uid);
- err = setxattr(path, "user.virtfs.uid", &tmp_uid, sizeof(uid_t), 0);
+ err = local_do_setxattr(fd, path, "user.virtfs.uid", &tmp_uid,
+ sizeof(uid_t));
if (err) {
return err;
}
}
if (credp->fc_gid != -1) {
uint32_t tmp_gid = cpu_to_le32(credp->fc_gid);
- err = setxattr(path, "user.virtfs.gid", &tmp_gid, sizeof(gid_t), 0);
+ err = local_do_setxattr(fd, path, "user.virtfs.gid", &tmp_gid,
+ sizeof(gid_t));
if (err) {
return err;
}
}
if (credp->fc_mode != -1) {
uint32_t tmp_mode = cpu_to_le32(credp->fc_mode);
- err = setxattr(path, "user.virtfs.mode", &tmp_mode, sizeof(mode_t), 0);
+ err = local_do_setxattr(fd, path, "user.virtfs.mode", &tmp_mode,
+ sizeof(mode_t));
if (err) {
return err;
}
}
if (credp->fc_rdev != -1) {
uint64_t tmp_rdev = cpu_to_le64(credp->fc_rdev);
- err = setxattr(path, "user.virtfs.rdev", &tmp_rdev, sizeof(dev_t), 0);
+ err = local_do_setxattr(fd, path, "user.virtfs.rdev", &tmp_rdev,
+ sizeof(dev_t));
if (err) {
return err;
}
@@ -489,7 +503,7 @@ static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
buffer = rpath(fs_ctx, path);
- ret = local_set_xattr(buffer, credp);
+ ret = local_set_xattr(-1, buffer, credp);
g_free(buffer);
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
return local_set_mapped_file_attr(fs_ctx, path, credp);
@@ -522,7 +536,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
if (err == -1) {
goto out;
}
- err = local_set_xattr(buffer, credp);
+ err = local_set_xattr(-1, buffer, credp);
if (err == -1) {
serrno = errno;
goto err_end;
@@ -584,7 +598,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
goto out;
}
credp->fc_mode = credp->fc_mode|S_IFDIR;
- err = local_set_xattr(buffer, credp);
+ err = local_set_xattr(-1, buffer, credp);
if (err == -1) {
serrno = errno;
goto err_end;
@@ -674,7 +688,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
}
credp->fc_mode = credp->fc_mode|S_IFREG;
/* Set cleint credentials in xattr */
- err = local_set_xattr(buffer, credp);
+ err = local_set_xattr(-1, buffer, credp);
if (err == -1) {
serrno = errno;
goto err_end;
@@ -760,7 +774,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
close(fd);
/* Set cleint credentials in symlink's xattr */
credp->fc_mode = credp->fc_mode|S_IFLNK;
- err = local_set_xattr(buffer, credp);
+ err = local_set_xattr(-1, buffer, credp);
if (err == -1) {
serrno = errno;
goto err_end;
@@ -932,7 +946,7 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
g_free(buffer);
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
buffer = rpath(fs_ctx, path);
- ret = local_set_xattr(buffer, credp);
+ ret = local_set_xattr(-1, buffer, credp);
g_free(buffer);
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
return local_set_mapped_file_attr(fs_ctx, path, credp);
@@ -1046,7 +1060,7 @@ static ssize_t local_lgetxattr(FsContext *ctx, V9fsPath *fs_path,
{
char *path = fs_path->data;
- return v9fs_get_xattr(ctx, path, name, value, size);
+ return v9fs_get_xattr(ctx, -1, path, name, value, size);
}
static ssize_t local_llistxattr(FsContext *ctx, V9fsPath *fs_path,
@@ -1054,7 +1068,7 @@ static ssize_t local_llistxattr(FsContext *ctx, V9fsPath *fs_path,
{
char *path = fs_path->data;
- return v9fs_list_xattr(ctx, path, value, size);
+ return v9fs_list_xattr(ctx, -1, path, value, size);
}
static int local_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
@@ -1062,7 +1076,7 @@ static int local_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
{
char *path = fs_path->data;
- return v9fs_set_xattr(ctx, path, name, value, size, flags);
+ return v9fs_set_xattr(ctx, -1, path, name, value, size, flags);
}
static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
@@ -1070,7 +1084,7 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
{
char *path = fs_path->data;
- return v9fs_remove_xattr(ctx, path, name);
+ return v9fs_remove_xattr(ctx, -1, path, name);
}
static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
@@ -22,19 +22,23 @@
#define ACL_ACCESS "system.posix_acl_access"
#define ACL_DEFAULT "system.posix_acl_default"
-static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
+static ssize_t mp_pacl_getxattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value, size_t size)
{
char *buffer;
ssize_t ret;
- buffer = rpath(ctx, path);
- ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size);
+ g_free(buffer);
+ } else {
+ ret = fgetxattr(fd, MAP_ACL_ACCESS, value, size);
+ }
return ret;
}
-static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
+static ssize_t mp_pacl_listxattr(FsContext *ctx, int fd, const char *path,
char *name, void *value, size_t osize)
{
ssize_t len = sizeof(ACL_ACCESS);
@@ -53,26 +57,36 @@ static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
return 0;
}
-static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
- void *value, size_t size, int flags)
+static int mp_pacl_setxattr(FsContext *ctx, int fd, const char *path,
+ const char *name, void *value, size_t size,
+ int flags)
{
char *buffer;
int ret;
- buffer = rpath(ctx, path);
- ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags);
+ g_free(buffer);
+ } else {
+ ret = fsetxattr(fd, MAP_ACL_ACCESS, value, size, flags);
+ }
return ret;
}
-static int mp_pacl_removexattr(FsContext *ctx,
+static int mp_pacl_removexattr(FsContext *ctx, int fd,
const char *path, const char *name)
{
int ret;
char *buffer;
- buffer = rpath(ctx, path);
- ret = lremovexattr(buffer, MAP_ACL_ACCESS);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lremovexattr(buffer, MAP_ACL_ACCESS);
+ } else {
+ buffer = NULL;
+ ret = fremovexattr(fd, MAP_ACL_ACCESS);
+ }
if (ret == -1 && errno == ENODATA) {
/*
* We don't get ENODATA error when trying to remove a
@@ -86,19 +100,23 @@ static int mp_pacl_removexattr(FsContext *ctx,
return ret;
}
-static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
+static ssize_t mp_dacl_getxattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value, size_t size)
{
char *buffer;
ssize_t ret;
- buffer = rpath(ctx, path);
- ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size);
+ g_free(buffer);
+ } else {
+ ret = fgetxattr(fd, MAP_ACL_DEFAULT, value, size);
+ }
return ret;
}
-static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
+static ssize_t mp_dacl_listxattr(FsContext *ctx, int fd, const char *path,
char *name, void *value, size_t osize)
{
ssize_t len = sizeof(ACL_DEFAULT);
@@ -117,26 +135,36 @@ static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
return 0;
}
-static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
- void *value, size_t size, int flags)
+static int mp_dacl_setxattr(FsContext *ctx, int fd, const char *path,
+ const char *name, void *value, size_t size,
+ int flags)
{
char *buffer;
int ret;
- buffer = rpath(ctx, path);
- ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags);
+ g_free(buffer);
+ } else {
+ ret = fsetxattr(fd, MAP_ACL_DEFAULT, value, size, flags);
+ }
return ret;
}
-static int mp_dacl_removexattr(FsContext *ctx,
+static int mp_dacl_removexattr(FsContext *ctx, int fd,
const char *path, const char *name)
{
int ret;
char *buffer;
- buffer = rpath(ctx, path);
- ret = lremovexattr(buffer, MAP_ACL_DEFAULT);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lremovexattr(buffer, MAP_ACL_DEFAULT);
+ } else {
+ buffer = NULL;
+ ret = fremovexattr(fd, MAP_ACL_DEFAULT);
+ }
if (ret == -1 && errno == ENODATA) {
/*
* We don't get ENODATA error when trying to remove a
@@ -17,7 +17,7 @@
#include "9p-xattr.h"
-static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
+static ssize_t mp_user_getxattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value, size_t size)
{
char *buffer;
@@ -31,13 +31,17 @@ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
errno = ENOATTR;
return -1;
}
- buffer = rpath(ctx, path);
- ret = lgetxattr(buffer, name, value, size);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lgetxattr(buffer, name, value, size);
+ g_free(buffer);
+ } else {
+ ret = fgetxattr(fd, name, value, size);
+ }
return ret;
}
-static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
+static ssize_t mp_user_listxattr(FsContext *ctx, int fd, const char *path,
char *name, void *value, size_t size)
{
int name_size = strlen(name) + 1;
@@ -70,8 +74,9 @@ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
return name_size;
}
-static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
- void *value, size_t size, int flags)
+static int mp_user_setxattr(FsContext *ctx, int fd, const char *path,
+ const char *name, void *value, size_t size,
+ int flags)
{
char *buffer;
int ret;
@@ -84,13 +89,17 @@ static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
errno = EACCES;
return -1;
}
- buffer = rpath(ctx, path);
- ret = lsetxattr(buffer, name, value, size, flags);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lsetxattr(buffer, name, value, size, flags);
+ g_free(buffer);
+ } else {
+ ret = fsetxattr(fd, name, value, size, flags);
+ }
return ret;
}
-static int mp_user_removexattr(FsContext *ctx,
+static int mp_user_removexattr(FsContext *ctx, int fd,
const char *path, const char *name)
{
char *buffer;
@@ -104,9 +113,13 @@ static int mp_user_removexattr(FsContext *ctx,
errno = EACCES;
return -1;
}
- buffer = rpath(ctx, path);
- ret = lremovexattr(buffer, name);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lremovexattr(buffer, name);
+ g_free(buffer);
+ } else {
+ ret = fremovexattr(fd, name);
+ }
return ret;
}
@@ -29,18 +29,18 @@ static XattrOperations *get_xattr_operations(XattrOperations **h,
return NULL;
}
-ssize_t v9fs_get_xattr(FsContext *ctx, const char *path,
+ssize_t v9fs_get_xattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value, size_t size)
{
XattrOperations *xops = get_xattr_operations(ctx->xops, name);
if (xops) {
- return xops->getxattr(ctx, path, name, value, size);
+ return xops->getxattr(ctx, fd, path, name, value, size);
}
errno = EOPNOTSUPP;
return -1;
}
-ssize_t pt_listxattr(FsContext *ctx, const char *path,
+ssize_t pt_listxattr(FsContext *ctx, int fd, const char *path,
char *name, void *value, size_t size)
{
int name_size = strlen(name) + 1;
@@ -63,7 +63,7 @@ ssize_t pt_listxattr(FsContext *ctx, const char *path,
* Get the list and pass to each layer to find out whether
* to send the data or not
*/
-ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
+ssize_t v9fs_list_xattr(FsContext *ctx, int fd, const char *path,
void *value, size_t vsize)
{
ssize_t size = 0;
@@ -74,8 +74,13 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
ssize_t xattr_len, parsed_len = 0, attr_len;
/* Get the actual len */
- buffer = rpath(ctx, path);
- xattr_len = llistxattr(buffer, value, 0);
+ if (path) {
+ buffer = rpath(ctx, path);
+ xattr_len = llistxattr(buffer, value, 0);
+ } else {
+ buffer = NULL;
+ xattr_len = flistxattr(fd, value, 0);
+ }
if (xattr_len <= 0) {
g_free(buffer);
return xattr_len;
@@ -83,7 +88,11 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
/* Now fetch the xattr and find the actual size */
orig_value = g_malloc(xattr_len);
- xattr_len = llistxattr(buffer, orig_value, xattr_len);
+ if (path) {
+ xattr_len = llistxattr(buffer, orig_value, xattr_len);
+ } else {
+ xattr_len = flistxattr(fd, orig_value, xattr_len);
+ }
g_free(buffer);
/* store the orig pointer */
@@ -95,9 +104,9 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
}
if (!value) {
- size += xops->listxattr(ctx, path, orig_value, value, vsize);
+ size += xops->listxattr(ctx, fd, path, orig_value, value, vsize);
} else {
- size = xops->listxattr(ctx, path, orig_value, value, vsize);
+ size = xops->listxattr(ctx, fd, path, orig_value, value, vsize);
if (size < 0) {
goto err_out;
}
@@ -119,24 +128,24 @@ err_out:
return size;
}
-int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
+int v9fs_set_xattr(FsContext *ctx, int fd, const char *path, const char *name,
void *value, size_t size, int flags)
{
XattrOperations *xops = get_xattr_operations(ctx->xops, name);
if (xops) {
- return xops->setxattr(ctx, path, name, value, size, flags);
+ return xops->setxattr(ctx, fd, path, name, value, size, flags);
}
errno = EOPNOTSUPP;
return -1;
}
-int v9fs_remove_xattr(FsContext *ctx,
+int v9fs_remove_xattr(FsContext *ctx, int fd,
const char *path, const char *name)
{
XattrOperations *xops = get_xattr_operations(ctx->xops, name);
if (xops) {
- return xops->removexattr(ctx, path, name);
+ return xops->removexattr(ctx, fd, path, name);
}
errno = EOPNOTSUPP;
return -1;
@@ -18,13 +18,13 @@
typedef struct xattr_operations
{
const char *name;
- ssize_t (*getxattr)(FsContext *ctx, const char *path,
+ ssize_t (*getxattr)(FsContext *ctx, int fd, const char *path,
const char *name, void *value, size_t size);
- ssize_t (*listxattr)(FsContext *ctx, const char *path,
+ ssize_t (*listxattr)(FsContext *ctx, int fd, const char *path,
char *name, void *value, size_t size);
- int (*setxattr)(FsContext *ctx, const char *path, const char *name,
+ int (*setxattr)(FsContext *ctx, int fd, const char *path, const char *name,
void *value, size_t size, int flags);
- int (*removexattr)(FsContext *ctx,
+ int (*removexattr)(FsContext *ctx, int fd,
const char *path, const char *name);
} XattrOperations;
@@ -41,54 +41,67 @@ extern XattrOperations *mapped_xattr_ops[];
extern XattrOperations *passthrough_xattr_ops[];
extern XattrOperations *none_xattr_ops[];
-ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, const char *name,
- void *value, size_t size);
-ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, void *value,
+ssize_t v9fs_get_xattr(FsContext *ctx, int fd, const char *path,
+ const char *name, void *value, size_t size);
+ssize_t v9fs_list_xattr(FsContext *ctx, int fd, const char *path, void *value,
size_t vsize);
-int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
+int v9fs_set_xattr(FsContext *ctx, int fd, const char *path, const char *name,
void *value, size_t size, int flags);
-int v9fs_remove_xattr(FsContext *ctx, const char *path, const char *name);
-ssize_t pt_listxattr(FsContext *ctx, const char *path, char *name, void *value,
- size_t size);
+int v9fs_remove_xattr(FsContext *ctx, int fd, const char *path,
+ const char *name);
+ssize_t pt_listxattr(FsContext *ctx, int fd, const char *path, char *name,
+ void *value, size_t size);
-static inline ssize_t pt_getxattr(FsContext *ctx, const char *path,
+static inline ssize_t pt_getxattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value, size_t size)
{
char *buffer;
ssize_t ret;
- buffer = rpath(ctx, path);
- ret = lgetxattr(buffer, name, value, size);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lgetxattr(buffer, name, value, size);
+ g_free(buffer);
+ } else {
+ ret = fgetxattr(fd, name, value, size);
+ }
return ret;
}
-static inline int pt_setxattr(FsContext *ctx, const char *path,
+static inline int pt_setxattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value,
size_t size, int flags)
{
char *buffer;
int ret;
- buffer = rpath(ctx, path);
- ret = lsetxattr(buffer, name, value, size, flags);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lsetxattr(buffer, name, value, size, flags);
+ g_free(buffer);
+ } else {
+ ret = fsetxattr(fd, name, value, size, flags);
+ }
return ret;
}
-static inline int pt_removexattr(FsContext *ctx,
+static inline int pt_removexattr(FsContext *ctx, int fd,
const char *path, const char *name)
{
char *buffer;
int ret;
- buffer = rpath(ctx, path);
- ret = lremovexattr(path, name);
- g_free(buffer);
+ if (path) {
+ buffer = rpath(ctx, path);
+ ret = lremovexattr(path, name);
+ g_free(buffer);
+ } else {
+ ret = fremovexattr(fd, name);
+ }
return ret;
}
-static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path,
+static inline ssize_t notsup_getxattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value,
size_t size)
{
@@ -96,7 +109,7 @@ static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path,
return -1;
}
-static inline int notsup_setxattr(FsContext *ctx, const char *path,
+static inline int notsup_setxattr(FsContext *ctx, int fd, const char *path,
const char *name, void *value,
size_t size, int flags)
{
@@ -104,13 +117,13 @@ static inline int notsup_setxattr(FsContext *ctx, const char *path,
return -1;
}
-static inline ssize_t notsup_listxattr(FsContext *ctx, const char *path,
+static inline ssize_t notsup_listxattr(FsContext *ctx, int fd, const char *path,
char *name, void *value, size_t size)
{
return 0;
}
-static inline int notsup_removexattr(FsContext *ctx,
+static inline int notsup_removexattr(FsContext *ctx, int fd,
const char *path, const char *name)
{
errno = ENOTSUP;
This patch adds the plumbing to be able to use fgetxattr(), fsetxattr(), flistxattr() and fremovexattr(). It does not change any functionality. Signed-off-by: Greg Kurz <groug@kaod.org> --- hw/9pfs/9p-local.c | 44 +++++++++++++++++--------- hw/9pfs/9p-posix-acl.c | 80 ++++++++++++++++++++++++++++++++--------------- hw/9pfs/9p-xattr-user.c | 41 ++++++++++++++++-------- hw/9pfs/9p-xattr.c | 35 +++++++++++++-------- hw/9pfs/9p-xattr.h | 67 ++++++++++++++++++++++++--------------- 5 files changed, 172 insertions(+), 95 deletions(-) ------------------------------------------------------------------------------ Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San Francisco, CA to explore cutting-edge tech and listen to tech luminaries present their vision of the future. This family event has something for everyone, including kids. Get more information and register today. http://sdm.link/attshape