diff options
Diffstat (limited to 'hw/virtio-9p.c')
-rw-r--r-- | hw/virtio-9p.c | 116 |
1 files changed, 39 insertions, 77 deletions
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index 867fcfa..0e87722 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -135,21 +135,16 @@ static void v9fs_do_seekdir(V9fsState *s, DIR *dir, off_t off) return s->ops->seekdir(&s->ctx, dir, off); } -static int v9fs_do_readv(V9fsState *s, int fd, const struct iovec *iov, - int iovcnt) +static int v9fs_do_preadv(V9fsState *s, int fd, const struct iovec *iov, + int iovcnt, int64_t offset) { - return s->ops->readv(&s->ctx, fd, iov, iovcnt); + return s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset); } -static off_t v9fs_do_lseek(V9fsState *s, int fd, off_t offset, int whence) +static int v9fs_do_pwritev(V9fsState *s, int fd, const struct iovec *iov, + int iovcnt, int64_t offset) { - return s->ops->lseek(&s->ctx, fd, offset, whence); -} - -static int v9fs_do_writev(V9fsState *s, int fd, const struct iovec *iov, - int iovcnt) -{ - return s->ops->writev(&s->ctx, fd, iov, iovcnt); + return s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset); } static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode) @@ -1975,7 +1970,7 @@ static void v9fs_read_post_rewinddir(V9fsState *s, V9fsReadState *vs, return; } -static void v9fs_read_post_readv(V9fsState *s, V9fsReadState *vs, ssize_t err) +static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err) { if (err < 0) { /* IO error return the error */ @@ -1989,12 +1984,16 @@ static void v9fs_read_post_readv(V9fsState *s, V9fsReadState *vs, ssize_t err) if (0) { print_sg(vs->sg, vs->cnt); } - vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt); + vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt, + vs->off); + if (vs->len > 0) { + vs->off += vs->len; + } } while (vs->len == -1 && errno == EINTR); if (vs->len == -1) { err = -errno; } - v9fs_read_post_readv(s, vs, err); + v9fs_read_post_preadv(s, vs, err); return; } vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total); @@ -2006,32 +2005,6 @@ out: qemu_free(vs); } -static void v9fs_read_post_lseek(V9fsState *s, V9fsReadState *vs, ssize_t err) -{ - if (err == -1) { - err = -errno; - goto out; - } - vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); - - if (vs->total < vs->count) { - do { - if (0) { - print_sg(vs->sg, vs->cnt); - } - vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt); - } while (vs->len == -1 && errno == EINTR); - if (vs->len == -1) { - err = -errno; - } - v9fs_read_post_readv(s, vs, err); - return; - } -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs) { ssize_t err = 0; @@ -2089,8 +2062,16 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu) } else if (vs->fidp->fid_type == P9_FID_FILE) { vs->sg = vs->iov; pdu_marshal(vs->pdu, vs->offset + 4, "v", vs->sg, &vs->cnt); - err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET); - v9fs_read_post_lseek(s, vs, err); + vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); + if (vs->total <= vs->count) { + vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt, + vs->off); + if (vs->len > 0) { + vs->off += vs->len; + } + err = vs->len; + v9fs_read_post_preadv(s, vs, err); + } return; } else if (vs->fidp->fid_type == P9_FID_XATTR) { v9fs_xattr_read(s, vs); @@ -2224,7 +2205,7 @@ out: return; } -static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs, +static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs, ssize_t err) { if (err < 0) { @@ -2239,49 +2220,25 @@ static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs, if (0) { print_sg(vs->sg, vs->cnt); } - vs->len = v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt); + vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, + vs->off); + if (vs->len > 0) { + vs->off += vs->len; + } } while (vs->len == -1 && errno == EINTR); if (vs->len == -1) { err = -errno; } - v9fs_write_post_writev(s, vs, err); + v9fs_write_post_pwritev(s, vs, err); return; } vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total); - err = vs->offset; out: complete_pdu(s, vs->pdu, err); qemu_free(vs); } -static void v9fs_write_post_lseek(V9fsState *s, V9fsWriteState *vs, ssize_t err) -{ - if (err == -1) { - err = -errno; - goto out; - } - vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); - - if (vs->total < vs->count) { - do { - if (0) { - print_sg(vs->sg, vs->cnt); - } - vs->len = v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt); - } while (vs->len == -1 && errno == EINTR); - if (vs->len == -1) { - err = -errno; - } - v9fs_write_post_writev(s, vs, err); - return; - } - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs) { int i, to_copy; @@ -2362,11 +2319,16 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu) err = -EINVAL; goto out; } - err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET); - - v9fs_write_post_lseek(s, vs, err); + vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); + if (vs->total <= vs->count) { + vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off); + if (vs->len > 0) { + vs->off += vs->len; + } + err = vs->len; + v9fs_write_post_pwritev(s, vs, err); + } return; - out: complete_pdu(s, vs->pdu, err); qemu_free(vs); |