From patchwork Sat Jun 18 17:49:08 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Aneesh Kumar K.V" X-Patchwork-Id: 893602 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5IHnXpZ020708 for ; Sat, 18 Jun 2011 17:49:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751845Ab1FRRt2 (ORCPT ); Sat, 18 Jun 2011 13:49:28 -0400 Received: from e23smtp09.au.ibm.com ([202.81.31.142]:43544 "EHLO e23smtp09.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751623Ab1FRRtX (ORCPT ); Sat, 18 Jun 2011 13:49:23 -0400 Received: from d23relay03.au.ibm.com (d23relay03.au.ibm.com [202.81.31.245]) by e23smtp09.au.ibm.com (8.14.4/8.13.1) with ESMTP id p5IHnKZf025108 for ; Sun, 19 Jun 2011 03:49:20 +1000 Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay03.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p5IHnKmP893046 for ; Sun, 19 Jun 2011 03:49:20 +1000 Received: from d23av02.au.ibm.com (loopback [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p5IHnKlu028528 for ; Sun, 19 Jun 2011 03:49:20 +1000 Received: from skywalker.in.ibm.com ([9.77.201.141]) by d23av02.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p5IHnAri028441; Sun, 19 Jun 2011 03:49:17 +1000 From: "Aneesh Kumar K.V" To: penberg@kernel.org Cc: kvm@vger.kernel.org, "Aneesh Kumar K.V" Subject: [PATCH 5/5] tools/kvm/9p: Simplify the handler Date: Sat, 18 Jun 2011 23:19:08 +0530 Message-Id: <1308419348-31934-5-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1308419348-31934-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> References: <1308419348-31934-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 18 Jun 2011 17:49:33 +0000 (UTC) Signed-off-by: Aneesh Kumar K.V --- tools/kvm/include/net/9p/9p.h | 1 - tools/kvm/virtio/9p.c | 261 +++++++++++++++++++++++------------------ 2 files changed, 147 insertions(+), 115 deletions(-) diff --git a/tools/kvm/include/net/9p/9p.h b/tools/kvm/include/net/9p/9p.h index cc11592..61ecff3 100644 --- a/tools/kvm/include/net/9p/9p.h +++ b/tools/kvm/include/net/9p/9p.h @@ -635,7 +635,6 @@ struct p9_twrite { u32 fid; u64 offset; u32 count; - u8 *data; }; struct p9_rwrite { diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c index ef2fbaf..f2b9299 100644 --- a/tools/kvm/virtio/9p.c +++ b/tools/kvm/virtio/9p.c @@ -67,6 +67,15 @@ struct p9_dev { struct pci_device_header pci_hdr; }; +struct p9_pdu { + u32 queue_head; + int offset; + u16 out_iov_cnt; + u16 in_iov_cnt; + struct iovec in_iov[VIRTQUEUE_NUM]; + struct iovec out_iov[VIRTQUEUE_NUM]; +}; + /* Warning: Immediately use value returned from this function */ static const char *rel_to_abs(struct p9_dev *p9dev, const char *path, char *abs_path) @@ -184,12 +193,12 @@ static void set_p9msg_hdr(struct p9_msg *msg, u32 size, u8 cmd, u16 tag) }; } -static bool virtio_p9_version(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_version(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_rversion *rversion = (struct p9_rversion *)outmsg->msg; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_rversion *rversion = (struct p9_rversion *)inmsg->msg; rversion->msize = 4096; rversion->version.len = strlen(VIRTIO_P9_VERSION); @@ -197,35 +206,35 @@ static bool virtio_p9_version(struct p9_dev *p9dev, struct p9_msg *msg, *outlen = VIRTIO_P9_HDR_LEN + rversion->version.len + sizeof(u16) + sizeof(u32); - set_p9msg_hdr(outmsg, *outlen, P9_RVERSION, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RVERSION, outmsg->tag); return true; } -static bool virtio_p9_clunk(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_clunk(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_tclunk *tclunk = (struct p9_tclunk *)msg->msg; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_tclunk *tclunk = (struct p9_tclunk *)outmsg->msg; close_fid(p9dev, tclunk->fid); *outlen = VIRTIO_P9_HDR_LEN; - set_p9msg_hdr(outmsg, *outlen, P9_RCLUNK, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RCLUNK, outmsg->tag); return true; } -static bool virtio_p9_open(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_open(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_topen *topen = (struct p9_topen *)msg->msg; - struct p9_ropen *ropen = (struct p9_ropen *)outmsg->msg; - struct p9_fid *new_fid = &p9dev->fids[topen->fid]; struct stat st; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_topen *topen = (struct p9_topen *)outmsg->msg; + struct p9_ropen *ropen = (struct p9_ropen *)inmsg->msg; + struct p9_fid *new_fid = &p9dev->fids[topen->fid]; if (lstat(new_fid->abs_path, &st) < 0) return false; @@ -239,28 +248,29 @@ static bool virtio_p9_open(struct p9_dev *p9dev, struct p9_msg *msg, new_fid->fd = open(new_fid->abs_path, omode2uflags(topen->mode)); *outlen = VIRTIO_P9_HDR_LEN + sizeof(*ropen); - set_p9msg_hdr(outmsg, *outlen, P9_ROPEN, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_ROPEN, outmsg->tag); return true; } -static bool virtio_p9_create(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_create(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_tcreate *tcreate = (struct p9_tcreate *)msg->msg; - struct p9_rcreate *rcreate = (struct p9_rcreate *)outmsg->msg; - struct p9_fid *fid = &p9dev->fids[tcreate->fid]; - struct stat st; u8 mode; u32 perm; + struct stat st; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_tcreate *tcreate = (struct p9_tcreate *)outmsg->msg; + struct p9_rcreate *rcreate = (struct p9_rcreate *)inmsg->msg; + struct p9_fid *fid = &p9dev->fids[tcreate->fid]; + rcreate->iounit = 0; /* Get last byte of the variable length struct */ - mode = *((u8 *)msg + msg->size - 1); - perm = *(u32 *)((u8 *)msg + msg->size - 5); + mode = *((u8 *)outmsg + outmsg->size - 1); + perm = *(u32 *)((u8 *)outmsg + outmsg->size - 5); sprintf(fid->path, "%s/%.*s", fid->path, tcreate->name.len, (char *)&tcreate->name.str); @@ -280,21 +290,22 @@ static bool virtio_p9_create(struct p9_dev *p9dev, struct p9_msg *msg, st2qid(&st, &rcreate->qid); *outlen = VIRTIO_P9_HDR_LEN + sizeof(*rcreate); - set_p9msg_hdr(outmsg, *outlen, P9_RCREATE, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RCREATE, outmsg->tag); return true; } -static bool virtio_p9_walk(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_walk(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_twalk *twalk = (struct p9_twalk *)msg->msg; - struct p9_rwalk *rwalk = (struct p9_rwalk *)outmsg->msg; + u8 i; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_twalk *twalk = (struct p9_twalk *)outmsg->msg; + struct p9_rwalk *rwalk = (struct p9_rwalk *)inmsg->msg; struct p9_str *str = twalk->wnames; struct p9_fid *new_fid = &p9dev->fids[twalk->newfid]; - u8 i; + rwalk->nwqid = 0; if (twalk->nwname) { @@ -306,7 +317,8 @@ static bool virtio_p9_walk(struct p9_dev *p9dev, struct p9_msg *msg, struct stat st; /* Format the new path we're 'walk'ing into */ - sprintf(tmp, "%s/%.*s", fid->path, str->len, (char *)&str->str); + sprintf(tmp, "%s/%.*s", fid->path, + str->len, (char *)&str->str); if (lstat(rel_to_abs(p9dev, tmp, full_path), &st) < 0) break; @@ -323,22 +335,23 @@ static bool virtio_p9_walk(struct p9_dev *p9dev, struct p9_msg *msg, new_fid->fid = twalk->newfid; } - *outlen = VIRTIO_P9_HDR_LEN + sizeof(u16) + sizeof(struct p9_qid) * rwalk->nwqid; - set_p9msg_hdr(outmsg, *outlen, P9_RWALK, msg->tag); + *outlen = VIRTIO_P9_HDR_LEN + sizeof(u16) + + sizeof(struct p9_qid)*rwalk->nwqid; + set_p9msg_hdr(inmsg, *outlen, P9_RWALK, outmsg->tag); return true; } -static bool virtio_p9_attach(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_attach(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_rattach *rattach = (struct p9_rattach *)outmsg->msg; - struct p9_tattach *tattach = (struct p9_tattach *)msg->msg; + u32 i; struct stat st; struct p9_fid *fid; - u32 i; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_rattach *rattach = (struct p9_rattach *)inmsg->msg; + struct p9_tattach *tattach = (struct p9_tattach *)outmsg->msg; /* Reset everything */ for (i = 0; i < VIRTIO_P9_MAX_FID; i++) @@ -355,7 +368,7 @@ static bool virtio_p9_attach(struct p9_dev *p9dev, struct p9_msg *msg, strcpy(fid->path, "/"); *outlen = VIRTIO_P9_HDR_LEN + sizeof(*rattach); - set_p9msg_hdr(outmsg, *outlen, P9_RATTACH, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RATTACH, outmsg->tag); return true; } @@ -400,14 +413,14 @@ static u32 virtio_p9_fill_stat(struct p9_dev *p9dev, const char *name, return rstat->stat.size + sizeof(u16); } -static bool virtio_p9_read(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_read(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_tread *tread = (struct p9_tread *)msg->msg; - struct p9_rread *rread = (struct p9_rread *)outmsg->msg; - struct p9_rstat *rstat = (struct p9_rstat *)iov[1].iov_base; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_tread *tread = (struct p9_tread *)outmsg->msg; + struct p9_rread *rread = (struct p9_rread *)inmsg->msg; + struct p9_rstat *rstat = (struct p9_rstat *)pdu->in_iov[1].iov_base; struct p9_fid *fid = &p9dev->fids[tread->fid]; struct stat st; @@ -429,29 +442,30 @@ static bool virtio_p9_read(struct p9_dev *p9dev, struct p9_msg *msg, cur = readdir(fid->dir); } } else { - iov[0].iov_base += VIRTIO_P9_HDR_LEN + sizeof(u32); - iov[0].iov_len -= VIRTIO_P9_HDR_LEN + sizeof(u32); - rread->count = preadv(fid->fd, iov, iniovcnt, tread->offset); + pdu->in_iov[0].iov_base += VIRTIO_P9_HDR_LEN + sizeof(u32); + pdu->in_iov[0].iov_len -= VIRTIO_P9_HDR_LEN + sizeof(u32); + rread->count = preadv(fid->fd, pdu->in_iov, + pdu->in_iov_cnt, tread->offset); if (rread->count > tread->count) rread->count = tread->count; } *outlen = VIRTIO_P9_HDR_LEN + sizeof(u32) + rread->count; - set_p9msg_hdr(outmsg, *outlen, P9_RREAD, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RREAD, outmsg->tag); return true; } -static bool virtio_p9_stat(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_stat(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_tstat *tstat = (struct p9_tstat *)msg->msg; - struct p9_rstat *rstat = (struct p9_rstat *)(outmsg->msg + sizeof(u16)); + u32 ret; struct stat st; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_tstat *tstat = (struct p9_tstat *)outmsg->msg; + struct p9_rstat *rstat = (struct p9_rstat *)(inmsg->msg + sizeof(u16)); struct p9_fid *fid = &p9dev->fids[tstat->fid]; - u32 ret; if (lstat(fid->abs_path, &st) < 0) return false; @@ -459,19 +473,20 @@ static bool virtio_p9_stat(struct p9_dev *p9dev, struct p9_msg *msg, ret = virtio_p9_fill_stat(p9dev, fid->path, &st, rstat); *outlen = VIRTIO_P9_HDR_LEN + ret + sizeof(u16); - set_p9msg_hdr(outmsg, *outlen, P9_RSTAT, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RSTAT, outmsg->tag); return true; } -static bool virtio_p9_wstat(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_wstat(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_twstat *twstat = (struct p9_twstat *)msg->msg; + int res = 0; struct p9_str *str; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_twstat *twstat = (struct p9_twstat *)outmsg->msg; struct p9_fid *fid = &p9dev->fids[twstat->fid]; - int res = 0; + if (twstat->stat.length != -1UL) res = ftruncate(fid->fd, twstat->stat.length); @@ -497,17 +512,17 @@ static bool virtio_p9_wstat(struct p9_dev *p9dev, struct p9_msg *msg, } *outlen = VIRTIO_P9_HDR_LEN; - set_p9msg_hdr(outmsg, *outlen, P9_RWSTAT, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RWSTAT, outmsg->tag); return res == 0; } -static bool virtio_p9_remove(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_remove(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg = iov[0].iov_base; - struct p9_tremove *tremove = (struct p9_tremove *)msg->msg; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_tremove *tremove = (struct p9_tremove *)outmsg->msg; struct p9_fid *fid = &p9dev->fids[tremove->fid]; close_fid(p9dev, tremove->fid); @@ -517,39 +532,32 @@ static bool virtio_p9_remove(struct p9_dev *p9dev, struct p9_msg *msg, unlink(fid->abs_path); *outlen = VIRTIO_P9_HDR_LEN; - set_p9msg_hdr(outmsg, *outlen, P9_RREMOVE, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RREMOVE, outmsg->tag); return true; } -static bool virtio_p9_write(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen) +static bool virtio_p9_write(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen) { - struct p9_msg *outmsg; - struct p9_rwrite *rwrite; - struct p9_twrite *twrite = (struct p9_twrite *)msg->msg; + struct p9_msg *inmsg = pdu->in_iov[0].iov_base; + struct p9_msg *outmsg = pdu->out_iov[0].iov_base; + struct p9_twrite *twrite = (struct p9_twrite *)outmsg->msg; + struct p9_rwrite *rwrite = (struct p9_rwrite *)inmsg->msg; struct p9_fid *fid = &p9dev->fids[twrite->fid]; - if (outiovcnt == 1) { - outmsg = iov[0].iov_base; - rwrite = (struct p9_rwrite *)outmsg->msg; - rwrite->count = pwrite(fid->fd, &twrite->data, - twrite->count, twrite->offset); - } else { - outmsg = iov[2].iov_base; - rwrite = (struct p9_rwrite *)outmsg->msg; - rwrite->count = pwrite(fid->fd, iov[1].iov_base, - twrite->count, twrite->offset); - } + + pdu->out_iov[0].iov_base += (sizeof(*outmsg) + sizeof(*twrite)); + pdu->out_iov[0].iov_len -= (sizeof(*outmsg) + sizeof(*twrite)); + rwrite->count = pwritev(fid->fd, pdu->out_iov, + pdu->out_iov_cnt, twrite->offset); *outlen = VIRTIO_P9_HDR_LEN + sizeof(u32); - set_p9msg_hdr(outmsg, *outlen, P9_RWRITE, msg->tag); + set_p9msg_hdr(inmsg, *outlen, P9_RWRITE, outmsg->tag); return true; } -typedef bool p9_handler(struct p9_dev *p9dev, struct p9_msg *msg, - u32 len, struct iovec *iov, - int outiovcnt, int iniovcnt, u32 *outlen); +typedef bool p9_handler(struct p9_dev *p9dev, + struct p9_pdu *pdu, u32 *outlen); static p9_handler *virtio_9p_handler [] = { [P9_TVERSION] = virtio_p9_version, @@ -565,30 +573,55 @@ static p9_handler *virtio_9p_handler [] = { [P9_TWRITE] = virtio_p9_write, }; +static struct p9_pdu *virtio_p9_pdu_init(struct kvm *kvm, struct virt_queue *vq) +{ + struct p9_pdu *pdu = calloc(1, sizeof(*pdu)); + if (!pdu) + return NULL; + + pdu->queue_head = virt_queue__get_inout_iov(kvm, vq, pdu->in_iov, + pdu->out_iov, + &pdu->in_iov_cnt, + &pdu->out_iov_cnt); + return pdu; +} + +static u8 virtio_p9_get_cmd(struct p9_pdu *pdu) +{ + struct p9_msg *msg; + /* + * we can peek directly into pdu for a u8 + * value. The host endianess won't be an issue + */ + msg = pdu->out_iov[0].iov_base; + return msg->cmd; +} + static bool virtio_p9_do_io_request(struct kvm *kvm, struct p9_dev_job *job) { + u8 cmd; u32 len = 0; - u16 out, in, head; - struct p9_msg *msg; p9_handler *handler; - struct virt_queue *vq; struct p9_dev *p9dev; - struct iovec iov[VIRTQUEUE_NUM]; + struct virt_queue *vq; + struct p9_pdu *p9pdu; vq = job->vq; p9dev = job->p9dev; - head = virt_queue__get_iov(vq, iov, &out, &in, kvm); - msg = iov[0].iov_base; - if (msg->cmd >= ARRAY_SIZE(virtio_9p_handler) || - !virtio_9p_handler[msg->cmd]) { - printf("Unsupported P9 message type: %u\n", msg->cmd); + p9pdu = virtio_p9_pdu_init(kvm, vq); + cmd = virtio_p9_get_cmd(p9pdu); + + if (cmd >= ARRAY_SIZE(virtio_9p_handler) || + !virtio_9p_handler[cmd]) { + printf("Unsupported P9 message type: %u\n", cmd); } else { - handler = virtio_9p_handler[msg->cmd]; - handler(p9dev, msg, iov[0].iov_len, iov+1, out, in, &len); + handler = virtio_9p_handler[cmd]; + handler(p9dev, p9pdu, &len); } - virt_queue__set_used_elem(vq, head, len); + virt_queue__set_used_elem(vq, p9pdu->queue_head, len); + free(p9pdu); return true; }