diff mbox

[4/5] hw/9pfs: Add fs driver specific details to fscontext

Message ID 1307382555-3907-4-git-send-email-aneesh.kumar@linux.vnet.ibm.com
State New
Headers show

Commit Message

Aneesh Kumar K.V June 6, 2011, 5:49 p.m. UTC
Add a new context flag PATHNAME_FSCONTEXT and indicate whether
the fs driver track fid using path names. Also add a private
pointer that help us to track fs driver specific values in there

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fsdev/file-op-9p.h         |    6 ++++
 hw/9pfs/codir.c            |    8 +++---
 hw/9pfs/cofile.c           |   16 ++++++------
 hw/9pfs/cofs.c             |   57 ++++++++++++++++++++++++++-----------------
 hw/9pfs/coxattr.c          |   16 ++++++------
 hw/9pfs/virtio-9p-device.c |    1 +
 hw/9pfs/virtio-9p-local.c  |    1 +
 hw/9pfs/virtio-9p.c        |   29 ++++++++++++++++------
 hw/9pfs/virtio-9p.h        |   21 ++++++++++++++++
 9 files changed, 104 insertions(+), 51 deletions(-)
diff mbox

Patch

diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index bd82fac..5d088d4 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -50,13 +50,19 @@  typedef struct FsCred
 
 struct xattr_operations;
 
+/* FsContext flag values */
+#define PATHNAME_FSCONTEXT 0x1
+
 typedef struct FsContext
 {
+    int flags;
     char *fs_root;
     SecModel fs_sm;
     uid_t uid;
     int open_flags;
     struct xattr_operations **xops;
+    /* fs driver specific data */
+    void *private;
 } FsContext;
 
 typedef struct V9fsPath {
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index 2c50df8..b379f93 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -76,7 +76,7 @@  int v9fs_co_mkdir(V9fsState *s, V9fsFidState *fidp, V9fsString *name,
     cred.fc_mode = mode;
     cred.fc_uid = uid;
     cred.fc_gid = gid;
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->mkdir(&s->ctx, &fidp->path, name->data,  &cred);
@@ -94,7 +94,7 @@  int v9fs_co_mkdir(V9fsState *s, V9fsFidState *fidp, V9fsString *name,
                 v9fs_path_free(&path);
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -102,7 +102,7 @@  int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path);
@@ -112,7 +112,7 @@  int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp)
                 err = 0;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     if (!err) {
         total_open_fd++;
         if (total_open_fd > open_fd_hw) {
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 69fad36..1a99adc 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -21,7 +21,7 @@  int v9fs_co_lstat(V9fsState *s, V9fsPath *path, struct stat *stbuf)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->lstat(&s->ctx, path, stbuf);
@@ -29,7 +29,7 @@  int v9fs_co_lstat(V9fsState *s, V9fsPath *path, struct stat *stbuf)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -51,7 +51,7 @@  int v9fs_co_open(V9fsState *s, V9fsFidState *fidp, int flags)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             fidp->fs.fd = s->ops->open(&s->ctx, &fidp->path, flags);
@@ -61,7 +61,7 @@  int v9fs_co_open(V9fsState *s, V9fsFidState *fidp, int flags)
                 err = 0;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     if (!err) {
         total_open_fd++;
         if (total_open_fd > open_fd_hw) {
@@ -88,7 +88,7 @@  int v9fs_co_open2(V9fsState *s, V9fsFidState *fidp, V9fsString *name, gid_t gid,
      * don't change. Read lock is fine because this fid cannot
      * be used by any other operation.
      */
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             fidp->fs.fd = s->ops->open2(&s->ctx, &fidp->path,
@@ -112,7 +112,7 @@  int v9fs_co_open2(V9fsState *s, V9fsFidState *fidp, V9fsString *name, gid_t gid,
                 v9fs_path_free(&path);
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     if (!err) {
         total_open_fd++;
         if (total_open_fd > open_fd_hw) {
@@ -160,7 +160,7 @@  int v9fs_co_link(V9fsState *s, V9fsFidState *oldfid,
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->link(&s->ctx, &oldfid->path,
@@ -169,7 +169,7 @@  int v9fs_co_link(V9fsState *s, V9fsFidState *oldfid,
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 233597b..76461bf 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -23,7 +23,7 @@  int v9fs_co_readlink(V9fsState *s, V9fsPath *path, V9fsString *buf)
     ssize_t len;
 
     buf->data = qemu_malloc(PATH_MAX);
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             len = s->ops->readlink(&s->ctx, path,
@@ -36,7 +36,7 @@  int v9fs_co_readlink(V9fsState *s, V9fsPath *path, V9fsString *buf)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     if (err) {
         qemu_free(buf->data);
         buf->data = NULL;
@@ -49,7 +49,7 @@  int v9fs_co_statfs(V9fsState *s, V9fsPath *path, struct statfs *stbuf)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->statfs(&s->ctx, path, stbuf);
@@ -57,7 +57,7 @@  int v9fs_co_statfs(V9fsState *s, V9fsPath *path, struct statfs *stbuf)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -68,7 +68,7 @@  int v9fs_co_chmod(V9fsState *s, V9fsPath *path, mode_t mode)
 
     cred_init(&cred);
     cred.fc_mode = mode;
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->chmod(&s->ctx, path, &cred);
@@ -76,7 +76,7 @@  int v9fs_co_chmod(V9fsState *s, V9fsPath *path, mode_t mode)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -85,7 +85,7 @@  int v9fs_co_utimensat(V9fsState *s, V9fsPath *path,
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->utimensat(&s->ctx, path, times);
@@ -93,7 +93,7 @@  int v9fs_co_utimensat(V9fsState *s, V9fsPath *path,
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -105,7 +105,7 @@  int v9fs_co_chown(V9fsState *s, V9fsPath *path, uid_t uid, gid_t gid)
     cred_init(&cred);
     cred.fc_uid = uid;
     cred.fc_gid = gid;
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->chown(&s->ctx, path, &cred);
@@ -113,7 +113,7 @@  int v9fs_co_chown(V9fsState *s, V9fsPath *path, uid_t uid, gid_t gid)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -121,7 +121,7 @@  int v9fs_co_truncate(V9fsState *s, V9fsPath *path, off_t size)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->truncate(&s->ctx, path, size);
@@ -129,7 +129,7 @@  int v9fs_co_truncate(V9fsState *s, V9fsPath *path, off_t size)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -145,7 +145,7 @@  int v9fs_co_mknod(V9fsState *s, V9fsFidState *fidp, V9fsString *name, uid_t uid,
     cred.fc_gid  = gid;
     cred.fc_mode = mode;
     cred.fc_rdev = dev;
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->mknod(&s->ctx, &fidp->path, name->data, &cred);
@@ -163,7 +163,7 @@  int v9fs_co_mknod(V9fsState *s, V9fsFidState *fidp, V9fsString *name, uid_t uid,
                 v9fs_path_free(&path);
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -172,7 +172,7 @@  int v9fs_co_remove(V9fsState *s, V9fsPath *path)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->remove(&s->ctx, path->data);
@@ -180,7 +180,7 @@  int v9fs_co_remove(V9fsState *s, V9fsPath *path)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -188,7 +188,7 @@  int v9fs_co_unlinkat(V9fsState *s, V9fsPath *path, V9fsString *name, int flags)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->unlinkat(&s->ctx, path, name->data, flags);
@@ -196,7 +196,7 @@  int v9fs_co_unlinkat(V9fsState *s, V9fsPath *path, V9fsString *name, int flags)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -243,7 +243,7 @@  int v9fs_co_symlink(V9fsState *s, V9fsFidState *dfidp, V9fsString *name,
     cred.fc_uid = dfidp->uid;
     cred.fc_gid = gid;
     cred.fc_mode = 0777;
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->symlink(&s->ctx, oldpath, &dfidp->path,
@@ -262,7 +262,7 @@  int v9fs_co_symlink(V9fsState *s, V9fsFidState *dfidp, V9fsString *name,
                 v9fs_path_free(&path);
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -274,9 +274,20 @@  int v9fs_co_name_to_path(V9fsState *s, V9fsPath *dirpath,
                          const char *name, V9fsPath *path)
 {
     int err;
-    err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
-    if (err < 0) {
-        err = -errno;
+
+    if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+        err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
+        if (err < 0) {
+            err = -errno;
+        }
+    } else {
+        v9fs_co_run_in_worker(
+            {
+                err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
+                if (err < 0) {
+                    err = -errno;
+                }
+            });
     }
     return err;
 }
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index b723240..dd2e4a5 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -21,7 +21,7 @@  int v9fs_co_llistxattr(V9fsState *s, V9fsPath *path, void *value, size_t size)
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->llistxattr(&s->ctx, path, value, size);
@@ -29,7 +29,7 @@  int v9fs_co_llistxattr(V9fsState *s, V9fsPath *path, void *value, size_t size)
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -39,7 +39,7 @@  int v9fs_co_lgetxattr(V9fsState *s, V9fsPath *path,
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->lgetxattr(&s->ctx, path,
@@ -49,7 +49,7 @@  int v9fs_co_lgetxattr(V9fsState *s, V9fsPath *path,
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -59,7 +59,7 @@  int v9fs_co_lsetxattr(V9fsState *s, V9fsPath *path,
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->lsetxattr(&s->ctx, path,
@@ -69,7 +69,7 @@  int v9fs_co_lsetxattr(V9fsState *s, V9fsPath *path,
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
 
@@ -78,7 +78,7 @@  int v9fs_co_lremovexattr(V9fsState *s, V9fsPath *path,
 {
     int err;
 
-    qemu_co_rwlock_rdlock(&s->rename_lock);
+    v9fs_path_read_lock(s);
     v9fs_co_run_in_worker(
         {
             err = s->ops->lremovexattr(&s->ctx, path, xattr_name->data);
@@ -86,6 +86,6 @@  int v9fs_co_lremovexattr(V9fsState *s, V9fsPath *path,
                 err = -errno;
             }
         });
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     return err;
 }
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 2243943..36dc799 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -130,6 +130,7 @@  VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
     memcpy(s->tag, conf->tag, len);
     s->tag_len = len;
     s->ctx.uid = -1;
+    s->ctx.flags = 0;
 
     s->ops = fse->ops;
     s->vdev.get_features = virtio_9p_get_features;
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 494ee75..1b6c323 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -647,6 +647,7 @@  static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
 
 static int local_init(FsContext *ctx)
 {
+    ctx->flags |= PATHNAME_FSCONTEXT;
     return 0;
 }
 
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index bc77387..f038877 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -2343,6 +2343,7 @@  out_nofid:
     complete_pdu(s, pdu, err);
 }
 
+/* Only works with path name based fid */
 static void v9fs_remove(void *opaque)
 {
     int32_t fid;
@@ -2358,6 +2359,11 @@  static void v9fs_remove(void *opaque)
         err = -EINVAL;
         goto out_nofid;
     }
+    /* if fs driver is not path based, return EOPNOTSUPP */
+    if (!pdu->s->ctx.flags & PATHNAME_FSCONTEXT) {
+        err = -EOPNOTSUPP;
+        goto out_err;
+    }
     /*
      * IF the file is unlinked, we cannot reopen
      * the file later. So don't reclaim fd
@@ -2476,6 +2482,7 @@  out_nofid:
     return err;
 }
 
+/* Only works with path name based fid */
 static void v9fs_rename(void *opaque)
 {
     int32_t fid;
@@ -2495,10 +2502,14 @@  static void v9fs_rename(void *opaque)
         goto out_nofid;
     }
     BUG_ON(fidp->fid_type != P9_FID_NONE);
-
-    qemu_co_rwlock_wrlock(&s->rename_lock);
+    /* if fs driver is not path based, return EOPNOTSUPP */
+    if (!pdu->s->ctx.flags & PATHNAME_FSCONTEXT) {
+        err = -EOPNOTSUPP;
+        goto out;
+    }
+    v9fs_path_write_lock(s);
     err = v9fs_complete_rename(s, fidp, newdirfid, &name);
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     if (!err) {
         err = offset;
     }
@@ -2563,9 +2574,11 @@  static int v9fs_complete_renameat(V9fsState *s, int32_t olddirfid,
     if (err < 0) {
         goto out;
     }
-    /* Only for path based fid  we need to do the below fixup */
-    v9fs_fix_fid_paths(s, &olddirfidp->path, old_name,
-                       &newdirfidp->path, new_name);
+    if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+        /* Only for path based fid  we need to do the below fixup */
+        v9fs_fix_fid_paths(s, &olddirfidp->path, old_name,
+                           &newdirfidp->path, new_name);
+    }
 out:
     if (olddirfidp) {
         put_fid(s, olddirfidp);
@@ -2588,9 +2601,9 @@  static void v9fs_renameat(void *opaque)
     pdu_unmarshal(pdu, offset, "dsds", &olddirfid,
                   &old_name, &newdirfid, &new_name);
 
-    qemu_co_rwlock_wrlock(&s->rename_lock);
+    v9fs_path_write_lock(s);
     err = v9fs_complete_renameat(s, olddirfid, &old_name, newdirfid, &new_name);
-    qemu_co_rwlock_unlock(&s->rename_lock);
+    v9fs_path_unlock(s);
     if (!err) {
         err = offset;
     }
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 23a0a5e..7daee35 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -389,6 +389,27 @@  static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
     return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
 }
 
+static inline void v9fs_path_write_lock(V9fsState *s)
+{
+    if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+        qemu_co_rwlock_wrlock(&s->rename_lock);
+    }
+}
+
+static inline void v9fs_path_read_lock(V9fsState *s)
+{
+    if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+        qemu_co_rwlock_rdlock(&s->rename_lock);
+    }
+}
+
+static inline void v9fs_path_unlock(V9fsState *s)
+{
+    if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+        qemu_co_rwlock_unlock(&s->rename_lock);
+    }
+}
+
 extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
 extern void virtio_9p_set_fd_limit(void);
 extern void v9fs_reclaim_fd(V9fsState *s);