diff mbox

tools/kvm/9p: Add error protocol reply

Message ID 1308474599-9832-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Aneesh Kumar K.V June 19, 2011, 9:09 a.m. UTC
Add RERROR and use that in open on failure

NOTE: All the protocol operation should handle like this.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 tools/kvm/virtio/9p.c |   37 ++++++++++++++++++++++++++++++-------
 1 files changed, 30 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c
index 558a713..0e885b5 100644
--- a/tools/kvm/virtio/9p.c
+++ b/tools/kvm/virtio/9p.c
@@ -209,6 +209,22 @@  static u16 virtio_p9_update_iov_cnt(struct iovec iov[], u32 count, int iov_cnt)
 	return i;
 }
 
+static void virtio_p9_error_reply(struct p9_dev *p9dev,
+				  struct p9_pdu *pdu, int err, u32 *outlen)
+{
+	char *err_str;
+	struct p9_msg *inmsg  = pdu->in_iov[0].iov_base;
+	struct p9_msg *outmsg = pdu->out_iov[0].iov_base;
+	struct p9_rerror *rerror  = (struct p9_rerror *)inmsg->msg;
+
+	err_str = strerror(err);
+	rerror->error.len = strlen(err_str);
+	memcpy(&rerror->error.str, err_str, rerror->error.len);
+
+	*outlen = VIRTIO_P9_HDR_LEN + rerror->error.len + sizeof(u16);
+	set_p9msg_hdr(inmsg, *outlen, P9_RERROR, outmsg->tag);
+}
+
 static bool virtio_p9_version(struct p9_dev *p9dev,
 			      struct p9_pdu *pdu, u32 *outlen)
 {
@@ -253,19 +269,26 @@  static bool virtio_p9_open(struct p9_dev *p9dev,
 	struct p9_fid *new_fid	= &p9dev->fids[topen->fid];
 
 	if (lstat(new_fid->abs_path, &st) < 0)
-		return false;
+		goto err_out;
 
 	st2qid(&st, &ropen->qid);
 	ropen->iounit = 0;
 
-	if (new_fid->is_dir)
-		new_fid->dir	= opendir(new_fid->abs_path);
-	else
-		new_fid->fd	= open(new_fid->abs_path, omode2uflags(topen->mode));
-
+	if (new_fid->is_dir) {
+		new_fid->dir = opendir(new_fid->abs_path);
+		if (!new_fid->dir)
+			goto err_out;
+	} else {
+		new_fid->fd  = open(new_fid->abs_path,
+				   omode2uflags(topen->mode) | O_NOFOLLOW);
+		if (new_fid->fd < 0)
+			goto err_out;
+	}
 	*outlen = VIRTIO_P9_HDR_LEN + sizeof(*ropen);
 	set_p9msg_hdr(inmsg, *outlen, P9_ROPEN, outmsg->tag);
-
+	return true;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
 	return true;
 }