qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 11/13] 9p: xattr fid to reference file fid


From: Greg Kurz
Subject: [Qemu-devel] [PATCH 11/13] 9p: xattr fid to reference file fid
Date: Mon, 27 Jun 2016 11:42:26 +0200
User-agent: StGit/0.17.1-dirty

The flistxattr() and fgetxattr() syscalls in the guest are implementend
with XATTRWALK. In v9fs_xattrwalk(), we then create a xattr fid to
hold the the file path, and retrieve the xattr from the fs backend with
llistxattr() or lgetxattr().

This patch brings file descriptor support to fids with type P9_FID_XATTR,
so that the backend can use flistxattr() and fgetxattr(). This is done by
keeping a reference to the original fid until the xattr fid gets clunked.

Xattr fids created during XATTRCREATE (setxattr/removexattr in the guest),
are not affected: the guest does not provide the related open fid and we
have no reference to keep. In this case, the xattr operation will continue
to be based on the path.

Signed-off-by: Greg Kurz <address@hidden>
---
 hw/9pfs/9p.c |   28 ++++++++++++++++++++++++----
 hw/9pfs/9p.h |    1 +
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 8824b71f364b..d02f95634b97 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -248,6 +248,12 @@ int v9fs_get_fd_fid(int fid_type, V9fsFidOpenState *fs)
         fd = dirfd(fs->dir.stream);
     } else if (fid_type == P9_FID_FILE) {
         fd = fs->fd;
+    } else if (fid_type == P9_FID_XATTR) {
+        V9fsFidState *fidp = fs->xattr.file;
+
+        if (fidp) {
+            return v9fs_get_fd_fid(fidp->fid_type, &fidp->fs);
+        }
     }
 
     return fd;
@@ -265,6 +271,12 @@ static bool fid_has_file(V9fsFidState *fidp)
         if (fidp->fs.fd > -1) {
             return true;
         }
+    } else if (fid_type == P9_FID_XATTR) {
+        V9fsFidState *file = fidp->fs.xattr.file;
+
+        if (file) {
+            return fid_has_file(file);
+        }
     }
 
     return false;
@@ -368,6 +380,8 @@ free_value:
     return retval;
 }
 
+static int put_fid(V9fsPDU *pdu, V9fsFidState *fidp);
+
 static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
 {
     int retval = 0;
@@ -382,7 +396,13 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
             retval = v9fs_co_closedir(pdu, &fidp->fs);
         }
     } else if (fidp->fid_type == P9_FID_XATTR) {
+        V9fsFidState *file_fidp = fidp->fs.xattr.file;
+
         retval = v9fs_xattr_fid_clunk(pdu, fidp);
+        if (file_fidp) {
+            fidp->fs.xattr.file = NULL;
+            put_fid(pdu, file_fidp);
+        }
     }
     v9fs_path_free(&fidp->path);
     g_free(fidp);
@@ -3125,6 +3145,10 @@ static void v9fs_xattrwalk(void *opaque)
         goto out;
     }
     v9fs_path_copy(&xattr_fidp->path, &file_fidp->path);
+    xattr_fidp->fid_type = P9_FID_XATTR;
+    xattr_fidp->fs.xattr.copied_len = -1;
+    xattr_fidp->fs.xattr.file = file_fidp;
+    file_fidp->ref++;
     if (name.data == NULL) {
         /*
          * listxattr request. Get the size first
@@ -3139,8 +3163,6 @@ static void v9fs_xattrwalk(void *opaque)
          * Read the xattr value
          */
         xattr_fidp->fs.xattr.len = size;
-        xattr_fidp->fid_type = P9_FID_XATTR;
-        xattr_fidp->fs.xattr.copied_len = -1;
         if (size) {
             xattr_fidp->fs.xattr.value = g_malloc(size);
             err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
@@ -3172,8 +3194,6 @@ static void v9fs_xattrwalk(void *opaque)
          * Read the xattr value
          */
         xattr_fidp->fs.xattr.len = size;
-        xattr_fidp->fid_type = P9_FID_XATTR;
-        xattr_fidp->fs.xattr.copied_len = -1;
         if (size) {
             xattr_fidp->fs.xattr.value = g_malloc(size);
             err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index d0ccc0089771..0b9db6bd8c38 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -164,6 +164,7 @@ typedef struct V9fsXattr
     void *value;
     V9fsString name;
     int flags;
+    V9fsFidState *file;
 } V9fsXattr;
 
 typedef struct V9fsDir {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]