@@ -147,6 +147,8 @@ struct FileOperations
int (*fchmod)(FsContext *, int, V9fsFidOpenState *, FsCred *);
ssize_t (*fgetxattr)(FsContext *, int, V9fsFidOpenState *,
const char *, void *, size_t);
+ ssize_t (*flistxattr)(FsContext *, int, V9fsFidOpenState *,
+ void *, size_t);
void *opaque;
};
@@ -502,6 +502,15 @@ static ssize_t handle_llistxattr(FsContext *ctx, V9fsPath *fs_path,
return ret;
}
+static ssize_t handle_flistxattr(FsContext *ctx, int fid_type,
+ V9fsFidOpenState *fs, void *value, size_t size)
+{
+ int fd;
+
+ fd = v9fs_get_fd_fid(fid_type, fs);
+ return flistxattr(fd, value, size);
+}
+
static int handle_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
void *value, size_t size, int flags)
{
@@ -747,4 +756,5 @@ FileOperations handle_ops = {
.fchown = handle_fchown,
.fchmod = handle_fchmod,
.fgetxattr = handle_fgetxattr,
+ .flistxattr = handle_flistxattr,
};
@@ -1122,6 +1122,15 @@ static ssize_t local_llistxattr(FsContext *ctx, V9fsPath *fs_path,
return v9fs_list_xattr(ctx, -1, path, value, size);
}
+static ssize_t local_flistxattr(FsContext *ctx, int fid_type,
+ V9fsFidOpenState *fs, void *value, size_t size)
+{
+ int fd;
+
+ fd = v9fs_get_fd_fid(fid_type, fs);
+ return v9fs_list_xattr(ctx, fd, NULL, value, size);
+}
+
static int local_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
void *value, size_t size, int flags)
{
@@ -1368,4 +1377,5 @@ FileOperations local_ops = {
.fchown = local_fchown,
.fchmod = local_fchmod,
.fgetxattr = local_fgetxattr,
+ .flistxattr = local_flistxattr,
};
@@ -1029,6 +1029,15 @@ static ssize_t proxy_llistxattr(FsContext *ctx, V9fsPath *fs_path,
return retval;
}
+static ssize_t proxy_flistxattr(FsContext *ctx, int fid_type,
+ V9fsFidOpenState *fs, void *value, size_t size)
+{
+ int fd;
+
+ fd = v9fs_get_fd_fid(fid_type, fs);
+ return flistxattr(fd, value, size);
+}
+
static int proxy_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
void *value, size_t size, int flags)
{
@@ -1263,4 +1272,5 @@ FileOperations proxy_ops = {
.fchown = proxy_fchown,
.fchmod = proxy_fchmod,
.fgetxattr = proxy_fgetxattr,
+ .flistxattr = proxy_flistxattr,
};
@@ -479,6 +479,13 @@ static ssize_t synth_llistxattr(FsContext *ctx, V9fsPath *path,
return -1;
}
+static ssize_t synth_flistxattr(FsContext *ctx, int fid_type,
+ V9fsFidOpenState *fs, void *value, size_t size)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
static int synth_lsetxattr(FsContext *ctx, V9fsPath *path,
const char *name, void *value,
size_t size, int flags)
@@ -607,4 +614,5 @@ FileOperations synth_ops = {
.fchown = synth_fchown,
.fchmod = synth_fchmod,
.fgetxattr = synth_fgetxattr,
+ .flistxattr = synth_flistxattr,
};
@@ -3125,6 +3125,16 @@ static int v9fs_do_getxattr(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name,
}
}
+static int v9fs_do_listxattr(V9fsPDU *pdu, V9fsFidState *fidp, void *value,
+ size_t size)
+{
+ if (fid_has_file(fidp)) {
+ return v9fs_co_flistxattr(pdu, fidp, value, size);
+ } else {
+ return v9fs_co_llistxattr(pdu, &fidp->path, value, size);
+ }
+}
+
static void v9fs_xattrwalk(void *opaque)
{
int64_t size;
@@ -3163,7 +3173,7 @@ static void v9fs_xattrwalk(void *opaque)
/*
* listxattr request. Get the size first
*/
- size = v9fs_co_llistxattr(pdu, &xattr_fidp->path, NULL, 0);
+ size = v9fs_do_listxattr(pdu, xattr_fidp, NULL, 0);
if (size < 0) {
err = size;
clunk_fid(s, xattr_fidp->fid);
@@ -3175,9 +3185,9 @@ static void v9fs_xattrwalk(void *opaque)
xattr_fidp->fs.xattr.len = size;
if (size) {
xattr_fidp->fs.xattr.value = g_malloc(size);
- err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
- xattr_fidp->fs.xattr.value,
- xattr_fidp->fs.xattr.len);
+ err = v9fs_do_listxattr(pdu, xattr_fidp,
+ xattr_fidp->fs.xattr.value,
+ xattr_fidp->fs.xattr.len);
if (err < 0) {
clunk_fid(s, xattr_fidp->fid);
goto out;
@@ -100,5 +100,6 @@ extern int v9fs_co_fchown(V9fsPDU *, V9fsFidState *, uid_t, gid_t);
extern int v9fs_co_fchmod(V9fsPDU *, V9fsFidState *, mode_t);
extern int v9fs_co_fgetxattr(V9fsPDU *, V9fsFidState *, V9fsString *, void *,
size_t);
+extern int v9fs_co_flistxattr(V9fsPDU *, V9fsFidState *, void *, size_t);
#endif
@@ -37,6 +37,26 @@ int v9fs_co_llistxattr(V9fsPDU *pdu, V9fsPath *path, void *value, size_t size)
return err;
}
+int v9fs_co_flistxattr(V9fsPDU *pdu, V9fsFidState *fidp, void *value,
+ size_t size)
+{
+ int err;
+ V9fsState *s = pdu->s;
+
+ if (v9fs_request_cancelled(pdu)) {
+ return -EINTR;
+ }
+ v9fs_co_run_in_worker(
+ {
+ err = s->ops->flistxattr(&s->ctx, fidp->fid_type, &fidp->fs, value,
+ size);
+ if (err < 0) {
+ err = -errno;
+ }
+ });
+ return err;
+}
+
int v9fs_co_lgetxattr(V9fsPDU *pdu, V9fsPath *path,
V9fsString *xattr_name,
void *value, size_t size)
This allows flistxattr() in the guest to stay functional even if the file was unlinked. Signed-off-by: Greg Kurz <groug@kaod.org> --- fsdev/file-op-9p.h | 2 ++ hw/9pfs/9p-handle.c | 10 ++++++++++ hw/9pfs/9p-local.c | 10 ++++++++++ hw/9pfs/9p-proxy.c | 10 ++++++++++ hw/9pfs/9p-synth.c | 8 ++++++++ hw/9pfs/9p.c | 18 ++++++++++++++---- hw/9pfs/coth.h | 1 + hw/9pfs/coxattr.c | 20 ++++++++++++++++++++ 8 files changed, 75 insertions(+), 4 deletions(-)