From patchwork Thu Sep 2 19:39:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jvrao X-Patchwork-Id: 63537 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 584ECB7140 for ; Fri, 3 Sep 2010 05:56:30 +1000 (EST) Received: from localhost ([127.0.0.1]:48576 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OrFsR-0005EQ-63 for incoming@patchwork.ozlabs.org; Thu, 02 Sep 2010 15:55:15 -0400 Received: from [140.186.70.92] (port=43619 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OrFTH-0004HS-8Q for qemu-devel@nongnu.org; Thu, 02 Sep 2010 15:29:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OrFTD-0004cs-73 for qemu-devel@nongnu.org; Thu, 02 Sep 2010 15:29:15 -0400 Received: from e33.co.us.ibm.com ([32.97.110.151]:56776) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OrFTD-0004cS-1g for qemu-devel@nongnu.org; Thu, 02 Sep 2010 15:29:11 -0400 Received: from d03relay05.boulder.ibm.com (d03relay05.boulder.ibm.com [9.17.195.107]) by e33.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id o82JOCfC018327 for ; Thu, 2 Sep 2010 13:24:12 -0600 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay05.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o82JT9Qc125410 for ; Thu, 2 Sep 2010 13:29:09 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id o82JT8bX021549 for ; Thu, 2 Sep 2010 13:29:08 -0600 Received: from localhost.localdomain (elm9m80.beaverton.ibm.com [9.47.81.80]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id o82JSwY0020779; Thu, 2 Sep 2010 13:29:07 -0600 From: "Venkateswararao Jujjuri (JV)" To: qemu-devel@nongnu.org Date: Thu, 2 Sep 2010 12:39:31 -0700 Message-Id: <1283456388-13083-12-git-send-email-jvrao@linux.vnet.ibm.com> X-Mailer: git-send-email 1.6.0.6 In-Reply-To: <1283456388-13083-1-git-send-email-jvrao@linux.vnet.ibm.com> References: <1283456388-13083-1-git-send-email-jvrao@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: aliguori@us.ibm.com, "Venkateswararao Jujjuri \(JV\)" Subject: [Qemu-devel] [PATCH -V5 11/28] [virtio-9p] Define and implement TSYMLINK for 9P2000.L X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch implements creating a symlink for TSYMLINK request and responds with RSYMLINK. In the case of error, we return RERROR. SYNOPSIS size[4] Tsymlink tag[2] fid[4] name[s] symtgt[s] gid[4] size[4] Rsymlink tag[2] qid[13] DESCRIPTION Create a symbolic link named 'name' pointing to 'symtgt'. gid represents the effective group id of the caller. The permissions of a symbolic link are irrelevant hence it is omitted from the protocol. Signed-off-by: Venkateswararao Jujjuri --- hw/virtio-9p-debug.c | 11 +++++++ hw/virtio-9p.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++---- hw/virtio-9p.h | 14 +++++++++ 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c index 2e61e9d..54179aa 100644 --- a/hw/virtio-9p-debug.c +++ b/hw/virtio-9p-debug.c @@ -464,6 +464,17 @@ void pprint_pdu(V9fsPDU *pdu) pprint_qid(pdu, 1, &offset, "qid"); pprint_int32(pdu, 1, &offset, ", iounit"); break; + case P9_TSYMLINK: + fprintf(llogfile, "TSYMLINK: ("); + pprint_int32(pdu, 0, &offset, "fid"); + pprint_str(pdu, 0, &offset, ", name"); + pprint_str(pdu, 0, &offset, ", symname"); + pprint_int32(pdu, 0, &offset, ", gid"); + break; + case P9_RSYMLINK: + fprintf(llogfile, "RSYMLINK: ("); + pprint_qid(pdu, 1, &offset, "qid"); + break; case P9_TREAD: fprintf(llogfile, "TREAD: ("); pprint_int32(pdu, 0, &offset, "fid"); diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index d1c3cf8..1036b49 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -200,15 +200,16 @@ static int v9fs_do_open2(V9fsState *s, V9fsCreateState *vs) return s->ops->open2(&s->ctx, vs->fullname.data, flags, &cred); } -static int v9fs_do_symlink(V9fsState *s, V9fsCreateState *vs) +static int v9fs_do_symlink(V9fsState *s, V9fsFidState *fidp, + const char *oldpath, const char *newpath, gid_t gid) { FsCred cred; cred_init(&cred); - cred.fc_uid = vs->fidp->uid; - cred.fc_mode = vs->perm | 0777; + cred.fc_uid = fidp->uid; + cred.fc_gid = gid; + cred.fc_mode = 0777; - return s->ops->symlink(&s->ctx, vs->extension.data, vs->fullname.data, - &cred); + return s->ops->symlink(&s->ctx, oldpath, newpath, &cred); } static int v9fs_do_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath) @@ -2212,7 +2213,8 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err) err = v9fs_do_mkdir(s, vs); v9fs_create_post_mkdir(s, vs, err); } else if (vs->perm & P9_STAT_MODE_SYMLINK) { - err = v9fs_do_symlink(s, vs); + err = v9fs_do_symlink(s, vs->fidp, vs->extension.data, + vs->fullname.data, -1); v9fs_create_post_perms(s, vs, err); } else if (vs->perm & P9_STAT_MODE_LINK) { int32_t nfid = atoi(vs->extension.data); @@ -2301,6 +2303,69 @@ out: qemu_free(vs); } +static void v9fs_post_symlink(V9fsState *s, V9fsSymlinkState *vs, int err) +{ + if (err == 0) { + stat_to_qid(&vs->stbuf, &vs->qid); + vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid); + err = vs->offset; + } else { + err = -errno; + } + complete_pdu(s, vs->pdu, err); + v9fs_string_free(&vs->name); + v9fs_string_free(&vs->symname); + v9fs_string_free(&vs->fullname); + qemu_free(vs); +} + +static void v9fs_symlink_post_do_symlink(V9fsState *s, V9fsSymlinkState *vs, + int err) +{ + if (err) { + goto out; + } + err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf); +out: + v9fs_post_symlink(s, vs, err); +} + +static void v9fs_symlink(V9fsState *s, V9fsPDU *pdu) +{ + int32_t dfid; + V9fsSymlinkState *vs; + int err = 0; + gid_t gid; + + vs = qemu_malloc(sizeof(*vs)); + vs->pdu = pdu; + vs->offset = 7; + + v9fs_string_init(&vs->fullname); + + pdu_unmarshal(vs->pdu, vs->offset, "dssd", &dfid, &vs->name, + &vs->symname, &gid); + + vs->dfidp = lookup_fid(s, dfid); + if (vs->dfidp == NULL) { + err = -EINVAL; + goto out; + } + + v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->dfidp->path.data, + vs->name.data); + err = v9fs_do_symlink(s, vs->dfidp, vs->symname.data, + vs->fullname.data, gid); + v9fs_symlink_post_do_symlink(s, vs, err); + return; + +out: + complete_pdu(s, vs->pdu, err); + v9fs_string_free(&vs->name); + v9fs_string_free(&vs->symname); + qemu_free(vs); +} + static void v9fs_flush(V9fsState *s, V9fsPDU *pdu) { /* A nop call with no return */ @@ -2718,6 +2783,7 @@ static pdu_handler_t *pdu_handlers[] = { #endif [P9_TFLUSH] = v9fs_flush, [P9_TLINK] = v9fs_link, + [P9_TSYMLINK] = v9fs_symlink, [P9_TCREATE] = v9fs_create, [P9_TWRITE] = v9fs_write, [P9_TWSTAT] = v9fs_wstat, diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h index d48776f..3671863 100644 --- a/hw/virtio-9p.h +++ b/hw/virtio-9p.h @@ -15,6 +15,8 @@ enum { P9_TSTATFS = 8, P9_RSTATFS, + P9_TSYMLINK = 16, + P9_RSYMLINK, P9_TGETATTR = 24, P9_RGETATTR, P9_TSETATTR = 26, @@ -294,6 +296,18 @@ typedef struct V9fsWstatState V9fsString nname; } V9fsWstatState; +typedef struct V9fsSymlinkState +{ + V9fsPDU *pdu; + size_t offset; + V9fsString name; + V9fsString symname; + V9fsString fullname; + V9fsFidState *dfidp; + V9fsQID qid; + struct stat stbuf; +} V9fsSymlinkState; + typedef struct V9fsIattr { int32_t valid;