From: Konstantin Khlebnikov <khlebnikov@openvz.org>
To: Sasha Levin <levinsasha928@gmail.com>
Cc: "penberg@kernel.org" <penberg@kernel.org>,
"mingo@elte.hu" <mingo@elte.hu>,
"asias.hejun@gmail.com" <asias.hejun@gmail.com>,
"gorcunov@gmail.com" <gorcunov@gmail.com>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>
Subject: Re: [PATCH 1/2 V2] kvm tools: Add scatter-gather variants of IO functions
Date: Sat, 16 Apr 2011 22:40:05 +0400 [thread overview]
Message-ID: <4DA9E285.5040308@openvz.org> (raw)
In-Reply-To: <1302966356-13145-1-git-send-email-levinsasha928@gmail.com>
one note below
Sasha Levin wrote:
> Added scatter-gather variants of [x,xp][read,write]() and [p]read_in_full().
>
> Signed-off-by: Sasha Levin<levinsasha928@gmail.com>
> ---
> tools/kvm/include/kvm/read-write.h | 13 +++
> tools/kvm/read-write.c | 172 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 185 insertions(+), 0 deletions(-)
>
> diff --git a/tools/kvm/include/kvm/read-write.h b/tools/kvm/include/kvm/read-write.h
> index 069326b..3351103 100644
> --- a/tools/kvm/include/kvm/read-write.h
> +++ b/tools/kvm/include/kvm/read-write.h
> @@ -2,6 +2,7 @@
> #define KVM_READ_WRITE_H
>
> #include<sys/types.h>
> +#include<sys/uio.h>
> #include<unistd.h>
>
> ssize_t xread(int fd, void *buf, size_t count);
> @@ -16,4 +17,16 @@ ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset);
> ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset);
> ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset);
>
> +ssize_t xreadv(int fd, const struct iovec *iov, int iovcnt);
> +ssize_t xwritev(int fd, const struct iovec *iov, int iovcnt);
> +
> +ssize_t readv_in_full(int fd, const struct iovec *iov, int iovcnt);
> +ssize_t writev_in_full(int fd, const struct iovec *iov, int iovcnt);
> +
> +ssize_t xpreadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
> +ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
> +
> +ssize_t preadv_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset);
> +ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset);
> +
> #endif /* KVM_READ_WRITE_H */
> diff --git a/tools/kvm/read-write.c b/tools/kvm/read-write.c
> index 398918b..449e8a2 100644
> --- a/tools/kvm/read-write.c
> +++ b/tools/kvm/read-write.c
> @@ -152,3 +152,175 @@ ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset)
>
> return total;
> }
> +
> +/* Same as readv(2) except that this function never returns EAGAIN or EINTR. */
> +ssize_t xreadv(int fd, const struct iovec *iov, int iovcnt)
> +{
> + ssize_t nr;
> +
> +restart:
> + nr = readv(fd, iov, iovcnt);
> + if ((nr< 0)&& ((errno == EAGAIN) || (errno == EINTR)))
> + goto restart;
> +
> + return nr;
> +}
> +
> +/* Same as writev(2) except that this function never returns EAGAIN or EINTR. */
> +ssize_t xwritev(int fd, const struct iovec *iov, int iovcnt)
> +{
> + ssize_t nr;
> +
> +restart:
> + nr = write(fd, iov, iovcnt);
> + if ((nr< 0)&& ((errno == EAGAIN) || (errno == EINTR)))
> + goto restart;
> +
> + return nr;
> +}
> +
> +static inline ssize_t get_iov_size(const struct iovec *iov, int iovcnt)
> +{
> + size_t size = 0;
> + while (iovcnt--)
> + size += (iov++)->iov_len;
> +
> + return size;
> +}
> +
> +ssize_t readv_in_full(int fd, const struct iovec *iov, int iovcnt)
> +{
> + ssize_t total = 0;
> + ssize_t count = get_iov_size(iov, iovcnt);
> +
> + while (count> 0) {
> + ssize_t nr;
> +
> + nr = xreadv(fd, iov, iovcnt);
> + if (nr<= 0) {
> + if (total> 0)
> + return total;
> +
> + return -1;
> + }
> +
> + while ((size_t)nr>= iov->iov_len) {
> + nr -= iov->iov_len;
> + total += iov->iov_len;
> + count -= iov->iov_len;
> + iovcnt--;
> + iov++;
> + }
> + }
> +
> + return total;
> +}
> +
> +ssize_t writev_in_full(int fd, const struct iovec *iov, int iovcnt)
> +{
> + ssize_t total = 0;
> + size_t count = get_iov_size(iov, iovcnt);
> +
> + while (count> 0) {
> + ssize_t nr;
> +
> + nr = xwritev(fd, iov, iovcnt);
> + if (nr< 0)
> + return -1;
> + if (nr == 0) {
> + errno = ENOSPC;
> + return -1;
> + }
> +
> + while ((size_t)nr>= iov->iov_len) {
> + nr -= iov->iov_len;
> + total += iov->iov_len;
> + count -= iov->iov_len;
> + iovcnt--;
> + iov++;
> + }
> + }
> +
> + return total;
> +}
> +
> +/* Same as preadv(2) except that this function never returns EAGAIN or EINTR. */
> +ssize_t xpreadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
> +{
> + ssize_t nr;
> +
> +restart:
> + nr = preadv(fd, iov, iovcnt, offset);
> + if ((nr< 0)&& ((errno == EAGAIN) || (errno == EINTR)))
> + goto restart;
> +
> + return nr;
> +}
> +
> +/* Same as pwritev(2) except that this function never returns EAGAIN or EINTR. */
> +ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
> +{
> + ssize_t nr;
> +
> +restart:
> + nr = pwritev(fd, iov, iovcnt, offset);
> + if ((nr< 0)&& ((errno == EAGAIN) || (errno == EINTR)))
> + goto restart;
> +
> + return nr;
> +}
> +
> +ssize_t preadv_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
> +{
> + ssize_t total = 0;
> + size_t count = get_iov_size(iov, iovcnt);
> +
> + while (count> 0) {
> + ssize_t nr;
> +
> + nr = xpreadv(fd, iov, iovcnt, offset);
> + if (nr<= 0) {
> + if (total> 0)
> + return total;
> +
> + return -1;
> + }
> +
> + while ((size_t)nr>= iov->iov_len) {
> + nr -= iov->iov_len;
> + total += iov->iov_len;
> + count -= iov->iov_len;
> + iovcnt--;
> + iov++;
> + }
> + }
> +
> + return total;
> +}
> +
> +ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
> +{
> + ssize_t total = 0;
> + size_t count = get_iov_size(iov, iovcnt);
> +
> + while (count> 0) {
> + ssize_t nr;
> +
> + nr = xpwritev(fd, iov, iovcnt, offset);
> + if (nr< 0)
> + return -1;
> + if (nr == 0) {
> + errno = ENOSPC;
> + return -1;
> + }
> + while ((size_t)nr>= iov->iov_len) {
> + nr -= iov->iov_len;
> + total += iov->iov_len;
> + count -= iov->iov_len;
> + iovcnt--;
> + iov++;
You forget here to change offset.
> + }
> + }
> +
> + return total;
> +}
It might be better to add an helper function, something like this:
static inline void shift_iovec(const struct iovec **iov, int *iovcnt,
size_t nr, ssize_t *total, off_t *offset)
{
while (nr >= (*iov)->iov_len) {
nr -= (*iov)->iov_len;
*total += (*iov)->iov_len;
*offset += (*iov)->iov_len;
*iovcnt--;
*iov++;
}
}
ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
{
ssize_t nr, total = 0;
while (iovcnt) {
nr = xpwritev(fd, iov, iovcnt, offset);
if (nr < 0)
return -1;
if (nr == 0) {
errno = ENOSPC;
return -1;
}
shift_iovec(&iov, &iovcnt, nr, &total, &offset);
}
return total;
}
next prev parent reply other threads:[~2011-04-16 18:40 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-16 15:05 [PATCH 1/2 V2] kvm tools: Add scatter-gather variants of IO functions Sasha Levin
2011-04-16 15:05 ` [PATCH 2/2 V2] kvm tools: Add scatter-gather support for disk images Sasha Levin
2011-04-16 18:40 ` Konstantin Khlebnikov [this message]
2011-04-16 20:33 ` [PATCH 1/2 V2] kvm tools: Add scatter-gather variants of IO functions Sasha Levin
2011-04-17 9:19 ` Avi Kivity
2011-04-17 10:03 ` Konstantin Khlebnikov
2011-04-17 10:22 ` Sasha Levin
2011-04-17 10:34 ` Konstantin Khlebnikov
2011-04-17 11:11 ` Sasha Levin
2011-04-17 12:49 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4DA9E285.5040308@openvz.org \
--to=khlebnikov@openvz.org \
--cc=asias.hejun@gmail.com \
--cc=gorcunov@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=levinsasha928@gmail.com \
--cc=mingo@elte.hu \
--cc=penberg@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.