[tip:tools/kvm] kvm tools: Save and restore the iovec related values in read and write

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit-ID:  e18399e3ce74b01e53338f7638e5df082a0cfcf0
Gitweb:     http://git.kernel.org/tip/e18399e3ce74b01e53338f7638e5df082a0cfcf0
Author:     Aneesh Kumar K.V <aneesh.kumar@xxxxxxxxxxxxxxxxxx>
AuthorDate: Tue, 9 Aug 2011 20:43:47 +0530
Committer:  Pekka Enberg <penberg@xxxxxxxxxx>
CommitDate: Wed, 10 Aug 2011 22:08:09 +0300

kvm tools: Save and restore the iovec related values in read and write

The virtio_p9_set_reply_header function looks at the pdu buffer to find the cmd
so that it can find the reply command value. We actually found the issue when
Sasha reported that dd on his system in failing with unknown error 512 with
dotl. The reason being that, since we didn't update iovec in virtio_p9_write
virtio_p9_set_reply_header was looking at a wrong offset and the reply cmd got
set to RLERROR, and the client picked the bytes written as errno number.

We need to restore the value properly so that rest of readf and writef
work as expected.

Cc: Sasha Levin <levinsasha928@xxxxxxxxx>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxx>
---
 tools/kvm/virtio/9p.c |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c
index 365c08e..ca9268a 100644
--- a/tools/kvm/virtio/9p.c
+++ b/tools/kvm/virtio/9p.c
@@ -487,6 +487,14 @@ static void virtio_p9_read(struct p9_dev *p9dev,
 			cur = readdir(fid->dir);
 		}
 	} else {
+		u16 iov_cnt;
+		void *iov_base;
+		size_t iov_len;
+
+		iov_base = pdu->in_iov[0].iov_base;
+		iov_len  = pdu->in_iov[0].iov_len;
+		iov_cnt  = pdu->in_iov_cnt;
+
 		pdu->in_iov[0].iov_base += VIRTIO_P9_HDR_LEN + sizeof(u32);
 		pdu->in_iov[0].iov_len -= VIRTIO_P9_HDR_LEN + sizeof(u32);
 		pdu->in_iov_cnt = virtio_p9_update_iov_cnt(pdu->in_iov,
@@ -500,9 +508,9 @@ static void virtio_p9_read(struct p9_dev *p9dev,
 		 * Update the iov_base back, so that rest of
 		 * pdu_writef works correctly.
 		 */
-		pdu->in_iov[0].iov_base -= VIRTIO_P9_HDR_LEN + sizeof(u32);
-		pdu->in_iov[0].iov_len += VIRTIO_P9_HDR_LEN + sizeof(u32);
-
+		pdu->in_iov[0].iov_base = iov_base;
+		pdu->in_iov[0].iov_len  = iov_len;
+		pdu->in_iov_cnt         = iov_cnt;
 	}
 	pdu->write_offset = VIRTIO_P9_HDR_LEN;
 	virtio_p9_pdu_writef(pdu, "d", rcount);
@@ -619,6 +627,9 @@ static void virtio_p9_write(struct p9_dev *p9dev,
 	u32 fid_val;
 	u32 count;
 	ssize_t res;
+	u16 iov_cnt;
+	void *iov_base;
+	size_t iov_len;
 	struct p9_fid *fid;
 	/* u32 fid + u64 offset + u32 count */
 	int twrite_size = sizeof(u32) + sizeof(u64) + sizeof(u32);
@@ -626,12 +637,23 @@ static void virtio_p9_write(struct p9_dev *p9dev,
 	virtio_p9_pdu_readf(pdu, "dqd", &fid_val, &offset, &count);
 	fid = &p9dev->fids[fid_val];
 
+	iov_base = pdu->out_iov[0].iov_base;
+	iov_len  = pdu->out_iov[0].iov_len;
+	iov_cnt  = pdu->out_iov_cnt;
+
 	/* Adjust the iovec to skip the header and meta data */
 	pdu->out_iov[0].iov_base += (sizeof(struct p9_msg) + twrite_size);
 	pdu->out_iov[0].iov_len -=  (sizeof(struct p9_msg) + twrite_size);
 	pdu->out_iov_cnt = virtio_p9_update_iov_cnt(pdu->out_iov, count,
 						    pdu->out_iov_cnt);
 	res = pwritev(fid->fd, pdu->out_iov, pdu->out_iov_cnt, offset);
+	/*
+	 * Update the iov_base back, so that rest of
+	 * pdu_readf works correctly.
+	 */
+	pdu->out_iov[0].iov_base = iov_base;
+	pdu->out_iov[0].iov_len  = iov_len;
+	pdu->out_iov_cnt         = iov_cnt;
 	if (res < 0)
 		goto err_out;
 	virtio_p9_pdu_writef(pdu, "d", res);
--
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Stable Commits]     [Linux Stable Kernel]     [Linux Kernel]     [Linux USB Devel]     [Linux Video &Media]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux