diff mbox

[V11,14/15] virtio-9p: readlink in chroot environment

Message ID 1308903744-2870-15-git-send-email-mohan@in.ibm.com
State New
Headers show

Commit Message

Mohan Kumar M June 24, 2011, 8:22 a.m. UTC
From: "M. Mohan Kumar" <mohan@in.ibm.com>


Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
---
 hw/9pfs/virtio-9p-chroot-worker.c |   17 ++++++++++++++---
 hw/9pfs/virtio-9p-chroot.h        |    1 +
 hw/9pfs/virtio-9p-local.c         |   14 ++++++++++++--
 3 files changed, 27 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/hw/9pfs/virtio-9p-chroot-worker.c b/hw/9pfs/virtio-9p-chroot-worker.c
index c4ebb96..0b87017 100644
--- a/hw/9pfs/virtio-9p-chroot-worker.c
+++ b/hw/9pfs/virtio-9p-chroot-worker.c
@@ -367,9 +367,6 @@  int v9fs_chroot(FsContext *fs_ctx)
         case T_CHOWN:
             retval = chroot_do_chown(&request);
             break;
-        default:
-            retval = -1;
-            break;
         case T_LSTAT:
             buff = qemu_malloc(request.data.size);
             retval = lstat(request.path.path, (struct stat *)buff);
@@ -377,6 +374,19 @@  int v9fs_chroot(FsContext *fs_ctx)
                 retval = -errno;
             }
             break;
+        case T_READLINK:
+            buff = qemu_malloc(request.data.size);
+            retval = readlink(request.path.path, buff, request.data.size);
+            if (retval < 0) {
+                retval = -errno;
+            } else {
+                buff[retval] = '\0';
+                retval = 0;
+            }
+            break;
+        default:
+            retval = -1;
+            break;
         }
 
         /* Send the results */
@@ -394,6 +404,7 @@  int v9fs_chroot(FsContext *fs_ctx)
             chroot_sendfd(chroot_sock, retval, valid_fd);
             break;
         case T_LSTAT:
+        case T_READLINK:
             chroot_sendspecial(chroot_sock, buff, request.data.size, retval);
             qemu_free(buff);
             break;
diff --git a/hw/9pfs/virtio-9p-chroot.h b/hw/9pfs/virtio-9p-chroot.h
index 9ed3f4d..ebf04b5 100644
--- a/hw/9pfs/virtio-9p-chroot.h
+++ b/hw/9pfs/virtio-9p-chroot.h
@@ -14,6 +14,7 @@ 
 #define T_CHMOD     9
 #define T_CHOWN     10
 #define T_LSTAT     11
+#define T_READLINK  12
 
 #define V9FS_FD_VALID INT_MAX
 
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index eab0854..e865cc8 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -96,6 +96,12 @@  static int passthrough_special_request(FsContext *fs_ctx, const char *path,
     request.data.size = size;
     if (type == T_LSTAT) {
         retval = v9fs_special(fs_ctx, &request, buff, size);
+    } else if (type == T_READLINK) {
+        retval = v9fs_special(fs_ctx, &request, buff, size);
+        /* readlink needs to return the number of bytes placed in buff */
+        if (retval >= 0) {
+            retval = size;
+        }
     } else {
             return -1;
     }
@@ -203,6 +209,11 @@  static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
     char buffer[PATH_MAX];
     char *path = fs_path->data;
 
+    if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+        return passthrough_special_request(fs_ctx, path, buf, bufsz,
+                        T_READLINK);
+    }
+
     if (fs_ctx->fs_sm == SM_MAPPED) {
         int fd;
         fd = open(rpath(fs_ctx, path, buffer), O_RDONLY);
@@ -214,8 +225,7 @@  static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
         } while (tsize == -1 && errno == EINTR);
         close(fd);
         return tsize;
-    } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
-               (fs_ctx->fs_sm == SM_NONE)) {
+    } else if (fs_ctx->fs_sm == SM_NONE) {
         tsize = readlink(rpath(fs_ctx, path, buffer), buf, bufsz);
     }
     return tsize;