Message ID | 1308419348-31934-5-git-send-email-aneesh.kumar@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Sat, 2011-06-18 at 23:19 +0530, Aneesh Kumar K.V wrote: > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> > --- > tools/kvm/include/net/9p/9p.h | 1 - > tools/kvm/virtio/9p.c | 261 +++++++++++++++++++++++------------------ > 2 files changed, 147 insertions(+), 115 deletions(-) After applying the patches (within a 9p mounted dir): # mkdir new_dir # cp 10MB new_dir/ cp: cannot create regular file `new_dir/10MB': No such file or directory > 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; > } >
On Sat, 18 Jun 2011 14:51:34 -0400, Sasha Levin <levinsasha928@gmail.com> wrote: > On Sat, 2011-06-18 at 23:19 +0530, Aneesh Kumar K.V wrote: > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> > > --- > > tools/kvm/include/net/9p/9p.h | 1 - > > tools/kvm/virtio/9p.c | 261 +++++++++++++++++++++++------------------ > > 2 files changed, 147 insertions(+), 115 deletions(-) > > After applying the patches (within a 9p mounted dir): > > # mkdir new_dir > # cp 10MB new_dir/ > cp: cannot create regular file `new_dir/10MB': No such file or directory > works fine here sh-2.05b# ls -al 10M -rwxr-xr-x 1 4294967294 4294967294 10485760 Jun 19 2011 10M sh-2.05b# mkdir new_dir sh-2.05b# cp 10M new_dir/ sh-2.05b# Can you check the before and after behaviour with the patch ? -aneesh -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, 2011-06-19 at 10:43 +0530, Aneesh Kumar K.V wrote: > On Sat, 18 Jun 2011 14:51:34 -0400, Sasha Levin <levinsasha928@gmail.com> wrote: > > On Sat, 2011-06-18 at 23:19 +0530, Aneesh Kumar K.V wrote: > > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> > > > --- > > > tools/kvm/include/net/9p/9p.h | 1 - > > > tools/kvm/virtio/9p.c | 261 +++++++++++++++++++++++------------------ > > > 2 files changed, 147 insertions(+), 115 deletions(-) > > > > After applying the patches (within a 9p mounted dir): > > > > # mkdir new_dir > > # cp 10MB new_dir/ > > cp: cannot create regular file `new_dir/10MB': No such file or directory > > > > works fine here > > sh-2.05b# ls -al 10M > -rwxr-xr-x 1 4294967294 4294967294 10485760 Jun 19 2011 10M > sh-2.05b# mkdir new_dir > sh-2.05b# cp 10M new_dir/ > sh-2.05b# > > Can you check the before and after behaviour with the patch ? It works ok before the patch here. I've added debug to the mount command, looks like it was caused due to patch 4/5 (the removal of one u16) - the host didn't quite like it :)
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; }
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> --- tools/kvm/include/net/9p/9p.h | 1 - tools/kvm/virtio/9p.c | 261 +++++++++++++++++++++++------------------ 2 files changed, 147 insertions(+), 115 deletions(-)