diff options
author | Sanchit Garg <sancgarg@linux.vnet.ibm.com> | 2010-10-08 11:30:16 +0530 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2010-10-20 12:10:59 -0500 |
commit | 56d15a53292c06a9c8c574e368003f57a06522ee (patch) | |
tree | 3b9dac4056f76e88c72f43b2984705b0a2f5eb86 /hw/virtio-9p-local.c | |
parent | 9f506893a454ce24263aba49594aa953e9a52853 (diff) |
[virtio-9p] Use preadv/pwritev instead of readv/writev
readv & writev, read & write respectively from the current offset
of the file & hence their use has to be preceeded by a call to lseek.
preadv/writev can be used instead, as they take the offset as an argument.
This saves one system call( lseek ).
In case preadv is not supported, it is implemented by an lseek
followed by a readv. Depending upon the configuration of QEMU, the
appropriate read & write methods are selected. This patch also fixes the
zero byte read/write bug & obviates the need to apply a fix for that bug separately.
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Signed-off-by: Sanchit Garg <sancgarg@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Diffstat (limited to 'hw/virtio-9p-local.c')
-rw-r--r-- | hw/virtio-9p-local.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c index ee630334b8..0d520201b4 100644 --- a/hw/virtio-9p-local.c +++ b/hw/virtio-9p-local.c @@ -168,21 +168,34 @@ static void local_seekdir(FsContext *ctx, DIR *dir, off_t off) return seekdir(dir, off); } -static ssize_t local_readv(FsContext *ctx, int fd, const struct iovec *iov, - int iovcnt) +static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov, + int iovcnt, off_t offset) { - return readv(fd, iov, iovcnt); -} - -static off_t local_lseek(FsContext *ctx, int fd, off_t offset, int whence) -{ - return lseek(fd, offset, whence); +#ifdef CONFIG_PREADV + return preadv(fd, iov, iovcnt, offset); +#else + int err = lseek(fd, offset, SEEK_SET); + if (err == -1) { + return err; + } else { + return readv(fd, iov, iovcnt); + } +#endif } -static ssize_t local_writev(FsContext *ctx, int fd, const struct iovec *iov, - int iovcnt) +static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, + int iovcnt, off_t offset) { - return writev(fd, iov, iovcnt); +#ifdef CONFIG_PREADV + return pwritev(fd, iov, iovcnt, offset); +#else + int err = lseek(fd, offset, SEEK_SET); + if (err == -1) { + return err; + } else { + return writev(fd, iov, iovcnt); + } +#endif } static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp) @@ -523,9 +536,8 @@ FileOperations local_ops = { .telldir = local_telldir, .readdir = local_readdir, .seekdir = local_seekdir, - .readv = local_readv, - .lseek = local_lseek, - .writev = local_writev, + .preadv = local_preadv, + .pwritev = local_pwritev, .chmod = local_chmod, .mknod = local_mknod, .mkdir = local_mkdir, |