From patchwork Mon Oct 31 20:53:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mohan Kumar M X-Patchwork-Id: 122968 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B8148B6F98 for ; Tue, 1 Nov 2011 08:48:45 +1100 (EST) Received: from localhost ([::1]:35512 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RKysi-0006H5-Sy for incoming@patchwork.ozlabs.org; Mon, 31 Oct 2011 16:54:56 -0400 Received: from eggs.gnu.org ([140.186.70.92]:43521) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RKyrv-0003oK-MK for qemu-devel@nongnu.org; Mon, 31 Oct 2011 16:54:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RKyrt-0000Dy-N5 for qemu-devel@nongnu.org; Mon, 31 Oct 2011 16:54:07 -0400 Received: from e23smtp05.au.ibm.com ([202.81.31.147]:38135) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RKyrs-0000DT-P9 for qemu-devel@nongnu.org; Mon, 31 Oct 2011 16:54:05 -0400 Received: from /spool/local by e23smtp05.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 31 Oct 2011 20:52:25 +1000 Received: from d23relay03.au.ibm.com ([202.81.31.245]) by e23smtp05.au.ibm.com ([202.81.31.211]) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 31 Oct 2011 20:52:23 +1000 Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay03.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p9VKs0tR2338904 for ; Tue, 1 Nov 2011 07:54:00 +1100 Received: from d23av03.au.ibm.com (loopback [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p9VKrxZP021191 for ; Tue, 1 Nov 2011 07:54:00 +1100 Received: from explorer.in.ibm.com ([9.79.185.111]) by d23av03.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p9VKreIG020950; Tue, 1 Nov 2011 07:53:58 +1100 From: "M. Mohan Kumar" To: qemu-devel@nongnu.org, aneesh.kumar@linux.vnet.ibm.com Date: Tue, 1 Nov 2011 02:23:27 +0530 Message-Id: <1320094412-19091-9-git-send-email-mohan@in.ibm.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1320094412-19091-1-git-send-email-mohan@in.ibm.com> References: <1320094412-19091-1-git-send-email-mohan@in.ibm.com> x-cbid: 11103110-1396-0000-0000-0000001DEBF8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 202.81.31.147 Cc: "M. Mohan Kumar" Subject: [Qemu-devel] [PATCH 08/13] hw/9pfs: Add stat/readlink/statfs for proxy FS X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "M. Mohan Kumar" Signed-off-by: M. Mohan Kumar --- hw/9pfs/proxy.h | 3 ++ hw/9pfs/virtfs-proxy-helper.c | 81 ++++++++++++++++++++++++++++++++++++++++- hw/9pfs/virtio-9p-proxy.c | 67 +++++++++++++++++++++++++++++++--- 3 files changed, 144 insertions(+), 7 deletions(-) diff --git a/hw/9pfs/proxy.h b/hw/9pfs/proxy.h index 5564eb5..5a13b5f 100644 --- a/hw/9pfs/proxy.h +++ b/hw/9pfs/proxy.h @@ -21,6 +21,9 @@ enum { T_MKDIR, T_SYMLINK, T_LINK, + T_LSTAT, + T_READLINK, + T_STATFS, }; #endif diff --git a/hw/9pfs/virtfs-proxy-helper.c b/hw/9pfs/virtfs-proxy-helper.c index 82aa267..9fa4a30 100644 --- a/hw/9pfs/virtfs-proxy-helper.c +++ b/hw/9pfs/virtfs-proxy-helper.c @@ -17,6 +17,7 @@ #include #include "bswap.h" #include +#include #include "qemu-common.h" #include "virtio-9p.h" #include "hw/9pfs/proxy.h" @@ -268,6 +269,59 @@ static int setfsugid(int uid, int gid) } /* + * send response in two parts + * 1) Size of the response + * 2) Response + * If there was a error send -errno only + */ +static int send_response(int sock, int size, char *response) +{ + int retval; + retval = socket_write(sock, &size, sizeof(size)); + if (retval > 0 && size > 0) { + retval = socket_write(sock, response, size); + } + if (size > 0) { + g_free(response); + } + return retval; +} + +static int do_stat(int type, struct iovec *iovec, char **response) +{ + V9fsString path; + int size = 0, retval = -1; + + v9fs_unmarshal(iovec, 1, 0, "s", &path); + + switch (type) { + case T_LSTAT: + size = sizeof(struct stat); + *response = g_malloc(size); + retval = lstat(path.data, (struct stat *)*response); + break; + case T_STATFS: + size = sizeof(struct statfs); + *response = g_malloc(size); + retval = statfs(path.data, (struct statfs *)*response); + break; + default: + retval = -EOPNOTSUPP; + goto error; + } + + if (retval < 0) { + retval = -errno; + g_free(*response); + } else { + retval = size; + } +error: + v9fs_string_free(&path); + return retval; +} + +/* * create a other filesystem objects and send 0 on success * return -errno on error */ @@ -368,6 +422,8 @@ static int process_requests(int sock) struct iovec iovec; int valid_fd; V9fsString oldpath, path; + char *response = NULL; + int size; iovec.iov_base = g_malloc(BUFF_SZ); iovec.iov_len = BUFF_SZ; @@ -401,6 +457,22 @@ static int process_requests(int sock) v9fs_string_free(&oldpath); v9fs_string_free(&path); break; + case T_LSTAT: + case T_STATFS: + retval = do_stat(type, &iovec, &response); + break; + case T_READLINK: + response = g_malloc(size); + v9fs_unmarshal(&iovec, 1, 0, "sd", &path, &size); + retval = readlink(path.data, response, size); + if (retval > 0) { + response[retval++] = '\0'; + } else { + retval = -errno; + g_free(response); + } + v9fs_string_free(&path); + break; default: goto error; break; @@ -416,11 +488,18 @@ static int process_requests(int sock) case T_LINK: sendfd(sock, retval, valid_fd); break; + case T_LSTAT: + case T_READLINK: + case T_STATFS: + if (send_response(sock, retval, response) < 0) { + do_perror("send_response"); + goto error; + } + break; default: break; } } - (void)socket_write; error: g_free(iovec.iov_base); return -1; diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/virtio-9p-proxy.c index 5f5eb35..1328e59 100644 --- a/hw/9pfs/virtio-9p-proxy.c +++ b/hw/9pfs/virtio-9p-proxy.c @@ -101,6 +101,7 @@ static int v9fs_request(V9fsProxy *proxy, int type, int sock_error, flags, mode, uid, gid; struct iovec *iovec = NULL; dev_t rdev; + int msg_size, size; qemu_mutex_lock(&proxy->mutex); @@ -175,6 +176,29 @@ static int v9fs_request(V9fsProxy *proxy, int type, v9fs_marshal(iovec, 1, 0, "dd", header.type, header.size); header.size += sizeof(header); break; + case T_LSTAT: + path = va_arg(ap, V9fsString *); + header.size = v9fs_marshal(iovec, 1, sizeof(ProxyHeader), "s", path); + header.type = T_LSTAT; + v9fs_marshal(iovec, 1, 0, "dd", header.type, header.size); + header.size += sizeof(header); + break; + case T_READLINK: + path = va_arg(ap, V9fsString *); + size = va_arg(ap, int); + header.size = v9fs_marshal(iovec, 1, sizeof(ProxyHeader), "sd", + path, size); + header.type = T_READLINK; + v9fs_marshal(iovec, 1, 0, "dd", header.type, header.size); + header.size += sizeof(header); + break; + case T_STATFS: + path = va_arg(ap, V9fsString *); + header.size = v9fs_marshal(iovec, 1, sizeof(ProxyHeader), "s", path); + header.type = T_STATFS; + v9fs_marshal(iovec, 1, 0, "dd", header.type, header.size); + header.size += sizeof(header); + break; default: fprintf(stderr, "Invalid type %d\n", type); goto close_error; @@ -202,6 +226,23 @@ static int v9fs_request(V9fsProxy *proxy, int type, goto close_error; } break; + case T_LSTAT: + case T_READLINK: + case T_STATFS: + retval = read(proxy->sockfd, &msg_size, sizeof(msg_size)); + if (retval != sizeof(msg_size)) { + goto close_error; + } + if (msg_size < 0) { + qemu_mutex_unlock(&proxy->mutex); + return msg_size; + } + retval = read(proxy->sockfd, response, msg_size); + if (retval != msg_size) { + goto close_error; + } + retval = 0; /* success */ + break; } qemu_mutex_unlock(&proxy->mutex); return retval; @@ -215,15 +256,25 @@ error: static int proxy_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf) { - errno = EOPNOTSUPP; - return -1; + int retval; + retval = v9fs_request(fs_ctx->private, T_LSTAT, stbuf, "s", fs_path); + if (retval < 0) { + errno = -retval; + } + return retval; } static ssize_t proxy_readlink(FsContext *fs_ctx, V9fsPath *fs_path, char *buf, size_t bufsz) { - errno = EOPNOTSUPP; - return -1; + int retval; + retval = v9fs_request(fs_ctx->private, T_READLINK, buf, "sd", + fs_path, bufsz); + if (retval < 0) { + errno = -retval; + return -1; + } + return strlen(buf); } static int proxy_close(FsContext *ctx, V9fsFidOpenState *fs) @@ -489,8 +540,12 @@ static int proxy_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync) static int proxy_statfs(FsContext *s, V9fsPath *fs_path, struct statfs *stbuf) { - errno = EOPNOTSUPP; - return -1; + int retval; + retval = v9fs_request(s->private, T_STATFS, stbuf, "s", fs_path); + if (retval < 0) { + errno = -retval; + } + return retval; } static ssize_t proxy_lgetxattr(FsContext *ctx, V9fsPath *fs_path,