From patchwork Tue Nov 15 11:57:40 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: 125778 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 3FE2AB6F6B for ; Tue, 15 Nov 2011 23:42:25 +1100 (EST) Received: from localhost ([::1]:34424 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RQHfQ-0003mw-N8 for incoming@patchwork.ozlabs.org; Tue, 15 Nov 2011 06:59:08 -0500 Received: from eggs.gnu.org ([140.186.70.92]:46977) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RQHeX-00015V-Ey for qemu-devel@nongnu.org; Tue, 15 Nov 2011 06:58:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RQHeV-0007hm-5h for qemu-devel@nongnu.org; Tue, 15 Nov 2011 06:58:13 -0500 Received: from e23smtp07.au.ibm.com ([202.81.31.140]:44122) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RQHeU-0007h8-Bg for qemu-devel@nongnu.org; Tue, 15 Nov 2011 06:58:11 -0500 Received: from d23relay04.au.ibm.com (d23relay04.au.ibm.com [202.81.31.246]) by e23smtp07.au.ibm.com (8.14.4/8.13.1) with ESMTP id pAFBw9pF002259 for ; Tue, 15 Nov 2011 22:58:09 +1100 Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pAFBt2L62855032 for ; Tue, 15 Nov 2011 22:55:02 +1100 Received: from d23av04.au.ibm.com (loopback [127.0.0.1]) by d23av04.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pAFBw87I019788 for ; Tue, 15 Nov 2011 22:58:08 +1100 Received: from explorer.in.ibm.com ([9.79.222.17]) by d23av04.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id pAFBvg6x018371; Tue, 15 Nov 2011 22:58:06 +1100 From: "M. Mohan Kumar" To: qemu-devel@nongnu.org, aneesh.kumar@linux.vnet.ibm.com, stefanha@gmail.com, berrange@redhat.com Date: Tue, 15 Nov 2011 17:27:40 +0530 Message-Id: <1321358265-10924-9-git-send-email-mohan@in.ibm.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1321358265-10924-1-git-send-email-mohan@in.ibm.com> References: <1321358265-10924-1-git-send-email-mohan@in.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 202.81.31.140 Subject: [Qemu-devel] [PATCH V2 08/12] hw/9pfs: xattr interfaces in proxy filesystem driver 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 Add xattr support for proxy FS Signed-off-by: M. Mohan Kumar --- fsdev/virtfs-proxy-helper.c | 78 ++++++++++++++++++++++++++++- hw/9pfs/virtio-9p-proxy.c | 119 +++++++++++++++++++++++++++++++++++++++---- hw/9pfs/virtio-9p-proxy.h | 4 ++ 3 files changed, 190 insertions(+), 11 deletions(-) diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c index ded0ead..ccd7ed8 100644 --- a/fsdev/virtfs-proxy-helper.c +++ b/fsdev/virtfs-proxy-helper.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "qemu-common.h" #include "virtio-9p-marshal.h" #include "hw/9pfs/virtio-9p-proxy.h" @@ -283,6 +284,50 @@ static int send_response(int sock, struct iovec *iovec, int size) return 0; } +static int do_getxattr(int type, struct iovec *iovec, struct iovec *out_iovec) +{ + int size = 0, offset, retval; + V9fsString path, name, xattr; + + v9fs_string_init(&xattr); + + offset = HDR_SZ; + offset += proxy_unmarshal(iovec, 1, HDR_SZ, "ds", &size, &path); + if (size) { + xattr.data = g_malloc(size); + xattr.size = size; + } + switch (type) { + case T_LGETXATTR: + proxy_unmarshal(iovec, 1, offset, "s", &name); + retval = lgetxattr(path.data, name.data, xattr.data, size); + if (retval < 0) { + retval = -errno; + v9fs_string_free(&name); + goto error; + } + v9fs_string_free(&name); + break; + case T_LLISTXATTR: + retval = llistxattr(path.data, xattr.data, size); + if (retval < 0) { + retval = -errno; + goto error; + } + break; + } + + if (!size) { + proxy_marshal(out_iovec, 1, HDR_SZ, "d", retval); + retval = sizeof(retval); + } else { + retval = proxy_marshal(out_iovec, 1, HDR_SZ, "s", &xattr); + } +error: + v9fs_string_free(&path); + return retval; +} + static void stat_to_prstat(ProxyStat *pr_stat, struct stat *stat) { memset(pr_stat, 0, sizeof(*pr_stat)); @@ -499,9 +544,10 @@ static int process_requests(int sock) int mode, uid, gid; struct timespec spec[2]; int type, retval = 0; + V9fsString name, value; V9fsString oldpath, path; struct iovec in_iovec, out_iovec; - int size = 0; + int size = 0, flags; in_iovec.iov_base = g_malloc(BUFF_SZ); in_iovec.iov_len = BUFF_SZ; @@ -595,6 +641,32 @@ static int process_requests(int sock) } v9fs_string_free(&path); break; + case T_LGETXATTR: + case T_LLISTXATTR: + size = do_getxattr(type, &in_iovec, &out_iovec); + break; + case T_LSETXATTR: + proxy_unmarshal(&in_iovec, 1, HDR_SZ, + "sssdd", &path, &name, &value, &size, + &flags); + retval = lsetxattr(path.data, name.data, value.data, size, flags); + if (retval < 0) { + retval = -errno; + } + v9fs_string_free(&path); + v9fs_string_free(&name); + v9fs_string_free(&value); + break; + case T_LREMOVEXATTR: + proxy_unmarshal(&in_iovec, 1, + HDR_SZ, "ss", &path, &name); + retval = lremovexattr(path.data, name.data); + if (retval < 0) { + retval = -errno; + } + v9fs_string_free(&path); + v9fs_string_free(&name); + break; default: goto error; break; @@ -616,11 +688,15 @@ static int process_requests(int sock) case T_UTIME: case T_RENAME: case T_REMOVE: + case T_LSETXATTR: + case T_LREMOVEXATTR: send_status(sock, &out_iovec, retval); break; case T_LSTAT: case T_STATFS: case T_READLINK: + case T_LGETXATTR: + case T_LLISTXATTR: if (send_response(sock, &out_iovec, size) < 0) { goto error; } diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/virtio-9p-proxy.c index aefdc61..f672ac3 100644 --- a/hw/9pfs/virtio-9p-proxy.c +++ b/hw/9pfs/virtio-9p-proxy.c @@ -136,7 +136,7 @@ static void prstat_to_stat(struct stat *stbuf, ProxyStat *prstat) * size of errno/response is given by header.size */ static int v9fs_receive_response(V9fsProxy *proxy, int type, - int *sock_error, void *response) + int *sock_error, int size, void *response) { int retval, error; ProxyHeader header; @@ -196,6 +196,19 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type, v9fs_string_free(&target); break; } + case T_LGETXATTR: + case T_LLISTXATTR: { + V9fsString xattr; + if (!size) { + proxy_unmarshal(reply, 1, HDR_SZ, "d", &size); + return size; + } else { + proxy_unmarshal(reply, 1, HDR_SZ, "s", &xattr); + memcpy(response, xattr.data, xattr.size); + v9fs_string_free(&xattr); + } + break; + } default: *sock_error = 1; return -1; @@ -244,6 +257,7 @@ static int v9fs_request(V9fsProxy *proxy, int type, int size = 0; struct timespec spec[2]; uint64_t offset; + V9fsString *name, *value; qemu_mutex_lock(&proxy->mutex); @@ -398,6 +412,44 @@ static int v9fs_request(V9fsProxy *proxy, int type, proxy_marshal(iovec, 1, 0, "dd", header.type, header.size); header.size += HDR_SZ; break; + case T_LGETXATTR: + size = va_arg(ap, int); + path = va_arg(ap, V9fsString *); + name = va_arg(ap, V9fsString *); + header.size = proxy_marshal(iovec, 1, HDR_SZ, "dss", size, + path, name); + header.type = T_LGETXATTR; + proxy_marshal(iovec, 1, 0, "dd", header.type, header.size); + header.size += HDR_SZ; + break; + case T_LLISTXATTR: + size = va_arg(ap, int); + path = va_arg(ap, V9fsString *); + header.size = proxy_marshal(iovec, 1, HDR_SZ, "ds", size, path); + header.type = T_LLISTXATTR; + proxy_marshal(iovec, 1, 0, "dd", header.type, header.size); + header.size += HDR_SZ; + break; + case T_LSETXATTR: + path = va_arg(ap, V9fsString *); + name = va_arg(ap, V9fsString *); + value = va_arg(ap, V9fsString *); + size = va_arg(ap, int); + flags = va_arg(ap, int); + header.size = proxy_marshal(iovec, 1, HDR_SZ, "sssdd", + path, name, value, size, flags); + header.type = T_LSETXATTR; + proxy_marshal(iovec, 1, 0, "dd", header.type, header.size); + header.size += HDR_SZ; + break; + case T_LREMOVEXATTR: + path = va_arg(ap, V9fsString *); + name = va_arg(ap, V9fsString *); + header.size = proxy_marshal(iovec, 1, HDR_SZ, "ss", path, name); + header.type = T_LREMOVEXATTR; + proxy_marshal(iovec, 1, 0, "dd", header.type, header.size); + header.size += HDR_SZ; + break; default: error_report("Invalid type %d\n", type); va_end(ap); @@ -433,6 +485,8 @@ static int v9fs_request(V9fsProxy *proxy, int type, case T_TRUNCATE: case T_UTIME: case T_REMOVE: + case T_LSETXATTR: + case T_LREMOVEXATTR: retval = v9fs_receive_status(proxy, &sock_error, reply); if (sock_error) { goto close_error; @@ -441,7 +495,10 @@ static int v9fs_request(V9fsProxy *proxy, int type, case T_LSTAT: case T_READLINK: case T_STATFS: - retval = v9fs_receive_response(proxy, type, &sock_error, response); + case T_LGETXATTR: + case T_LLISTXATTR: + retval = v9fs_receive_response(proxy, type, &sock_error, size, + response); if (sock_error) { goto close_error; } @@ -807,29 +864,71 @@ static int proxy_statfs(FsContext *s, V9fsPath *fs_path, struct statfs *stbuf) static ssize_t proxy_lgetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name, void *value, size_t size) { - errno = EOPNOTSUPP; - return -1; + int retval; + V9fsString xname; + + v9fs_string_init(&xname); + v9fs_string_sprintf(&xname, "%s", name); + retval = v9fs_request(ctx->private, T_LGETXATTR, value, "dss", size, + fs_path, &xname); + v9fs_string_free(&xname); + if (retval < 0) { + errno = -retval; + } + return retval; } static ssize_t proxy_llistxattr(FsContext *ctx, V9fsPath *fs_path, void *value, size_t size) { - errno = EOPNOTSUPP; - return -1; + int retval; + retval = v9fs_request(ctx->private, T_LLISTXATTR, value, "ds", size, + fs_path); + if (retval < 0) { + errno = -retval; + } + return retval; } static int proxy_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name, void *value, size_t size, int flags) { - errno = EOPNOTSUPP; - return -1; + int retval; + V9fsString xname, xvalue; + + v9fs_string_init(&xname); + v9fs_string_sprintf(&xname, "%s", name); + + v9fs_string_init(&xvalue); + xvalue.size = size; + xvalue.data = g_malloc(size); + memcpy(xvalue.data, value, size); + + retval = v9fs_request(ctx->private, T_LSETXATTR, value, "sssdd", + fs_path, &xname, &xvalue, size, flags); + v9fs_string_free(&xname); + v9fs_string_free(&xvalue); + if (retval < 0) { + errno = -retval; + } + return retval; } static int proxy_lremovexattr(FsContext *ctx, V9fsPath *fs_path, const char *name) { - errno = EOPNOTSUPP; - return -1; + int retval; + V9fsString xname; + + v9fs_string_init(&xname); + v9fs_string_sprintf(&xname, "%s", name); + retval = v9fs_request(ctx->private, T_LREMOVEXATTR, NULL, "ss", + fs_path, &xname); + v9fs_string_free(&xname); + if (retval < 0) { + errno = -retval; + } + return retval; } static int proxy_name_to_path(FsContext *ctx, V9fsPath *dir_path, diff --git a/hw/9pfs/virtio-9p-proxy.h b/hw/9pfs/virtio-9p-proxy.h index ef8a0f3..4c691a8 100644 --- a/hw/9pfs/virtio-9p-proxy.h +++ b/hw/9pfs/virtio-9p-proxy.h @@ -39,6 +39,10 @@ enum { T_UTIME, T_RENAME, T_REMOVE, + T_LGETXATTR, + T_LLISTXATTR, + T_LSETXATTR, + T_LREMOVEXATTR, }; typedef struct {