From patchwork Sun Jul 10 17:59:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Aneesh Kumar K.V" X-Patchwork-Id: 961632 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p6AI0ZB9003341 for ; Sun, 10 Jul 2011 18:00:36 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756038Ab1GJSAW (ORCPT ); Sun, 10 Jul 2011 14:00:22 -0400 Received: from e23smtp04.au.ibm.com ([202.81.31.146]:51653 "EHLO e23smtp04.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755717Ab1GJSAV (ORCPT ); Sun, 10 Jul 2011 14:00:21 -0400 Received: from d23relay05.au.ibm.com (d23relay05.au.ibm.com [202.81.31.247]) by e23smtp04.au.ibm.com (8.14.4/8.13.1) with ESMTP id p6AHrvW2020880 for ; Mon, 11 Jul 2011 03:53:57 +1000 Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay05.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p6AHwbLX1323260 for ; Mon, 11 Jul 2011 03:58:37 +1000 Received: from d23av02.au.ibm.com (loopback [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p6AI0AEm004003 for ; Mon, 11 Jul 2011 04:00:10 +1000 Received: from skywalker.ibm.com ([9.124.94.236]) by d23av02.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p6AI070f003138; Mon, 11 Jul 2011 04:00:08 +1000 From: "Aneesh Kumar K.V" To: penberg@kernel.org, levinsasha928@gmail.com Cc: kvm@vger.kernel.org, "Aneesh Kumar K.V" Subject: [PATCH] tools/kvm/9p: Add error handling to protocol handlers Date: Sun, 10 Jul 2011 23:29:16 +0530 Message-Id: <1310320756-5800-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.4.1 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Sun, 10 Jul 2011 18:00:36 +0000 (UTC) Signed-off-by: Aneesh Kumar K.V --- tools/kvm/virtio/9p.c | 73 ++++++++++++++++++++++++++++++++++++------------- 1 files changed, 54 insertions(+), 19 deletions(-) diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c index 3d46433..7e90024 100644 --- a/tools/kvm/virtio/9p.c +++ b/tools/kvm/virtio/9p.c @@ -236,6 +236,9 @@ err_out: static void virtio_p9_create(struct p9_dev *p9dev, struct p9_pdu *pdu, u32 *outlen) { + DIR *dir; + int fd; + int res; u8 mode; u32 perm; char *name; @@ -243,24 +246,33 @@ static void virtio_p9_create(struct p9_dev *p9dev, struct stat st; struct p9_qid qid; struct p9_fid *fid; + char full_path[PATH_MAX]; virtio_p9_pdu_readf(pdu, "dsdb", &fid_val, &name, &perm, &mode); fid = &p9dev->fids[fid_val]; - sprintf(fid->path, "%s/%.*s", fid->path, (int)strlen(name), name); - close_fid(p9dev, fid_val); - + sprintf(full_path, "%s/%s", fid->abs_path, name); if (perm & P9_DMDIR) { - mkdir(fid->abs_path, perm & 0xFFFF); - fid->dir = opendir(fid->abs_path); + res = mkdir(full_path, perm & 0xFFFF); + if (res < 0) + goto err_out; + dir = opendir(full_path); + if (!dir) + goto err_out; + close_fid(p9dev, fid_val); + fid->dir = dir; fid->is_dir = 1; } else { - fid->fd = open(fid->abs_path, - omode2uflags(mode) | O_CREAT, 0777); + fd = open(full_path, omode2uflags(mode) | O_CREAT, 0777); + if (fd < 0) + goto err_out; + close_fid(p9dev, fid_val); + fid->fd = fd; } - if (lstat(fid->abs_path, &st) < 0) + if (lstat(full_path, &st) < 0) goto err_out; + sprintf(fid->path, "%s/%s", fid->path, name); st2qid(&st, &qid); virtio_p9_pdu_writef(pdu, "Qd", &qid, 0); *outlen = pdu->write_offset; @@ -493,12 +505,16 @@ static void virtio_p9_wstat(struct p9_dev *p9dev, virtio_p9_pdu_readf(pdu, "dwS", &fid_val, &unused, &wstat); fid = &p9dev->fids[fid_val]; - if (wstat.length != -1UL) + if (wstat.length != -1UL) { res = ftruncate(fid->fd, wstat.length); - - if (wstat.mode != -1U) - chmod(fid->abs_path, wstat.mode & 0xFFFF); - + if (res < 0) + goto err_out; + } + if (wstat.mode != -1U) { + res = chmod(fid->abs_path, wstat.mode & 0xFFFF); + if (res < 0) + goto err_out; + } if (strlen(wstat.name) > 0) { char new_name[PATH_MAX] = {0}; char full_path[PATH_MAX]; @@ -512,17 +528,24 @@ static void virtio_p9_wstat(struct p9_dev *p9dev, wstat.name, strlen(wstat.name)); /* fid is reused for the new file */ - rename(fid->abs_path, rel_to_abs(p9dev, new_name, full_path)); + res = rename(fid->abs_path, + rel_to_abs(p9dev, new_name, full_path)); + if (res < 0) + goto err_out; sprintf(fid->path, "%s", new_name); } *outlen = VIRTIO_P9_HDR_LEN; virtio_p9_set_reply_header(pdu, *outlen); return; +err_out: + virtio_p9_error_reply(p9dev, pdu, errno, outlen); + return; } static void virtio_p9_remove(struct p9_dev *p9dev, struct p9_pdu *pdu, u32 *outlen) { + int res; u32 fid_val; struct p9_fid *fid; @@ -530,21 +553,28 @@ static void virtio_p9_remove(struct p9_dev *p9dev, fid = &p9dev->fids[fid_val]; close_fid(p9dev, fid_val); if (fid->is_dir) - rmdir(fid->abs_path); + res = rmdir(fid->abs_path); else - unlink(fid->abs_path); + res = unlink(fid->abs_path); + if (res < 0) + goto err_out; *outlen = VIRTIO_P9_HDR_LEN; virtio_p9_set_reply_header(pdu, *outlen); return; +err_out: + virtio_p9_error_reply(p9dev, pdu, errno, outlen); + return; } static void virtio_p9_write(struct p9_dev *p9dev, struct p9_pdu *pdu, u32 *outlen) { + u64 offset; u32 fid_val; - u32 count, rcount; + u32 count; + ssize_t res; struct p9_fid *fid; /* u32 fid + u64 offset + u32 count */ int twrite_size = sizeof(u32) + sizeof(u64) + sizeof(u32); @@ -557,11 +587,16 @@ static void virtio_p9_write(struct p9_dev *p9dev, 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); - rcount = pwritev(fid->fd, pdu->out_iov, pdu->out_iov_cnt, offset); - virtio_p9_pdu_writef(pdu, "d", rcount); + res = pwritev(fid->fd, pdu->out_iov, pdu->out_iov_cnt, offset); + if (res < 0) + goto err_out; + virtio_p9_pdu_writef(pdu, "d", res); *outlen = pdu->write_offset; virtio_p9_set_reply_header(pdu, *outlen); return; +err_out: + virtio_p9_error_reply(p9dev, pdu, errno, outlen); + return; } typedef void p9_handler(struct p9_dev *p9dev,