From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IqXvP-0008SV-B3 for qemu-devel@nongnu.org; Fri, 09 Nov 2007 12:45:47 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IqXvO-0008Rn-IY for qemu-devel@nongnu.org; Fri, 09 Nov 2007 12:45:46 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IqXvO-0008Rg-5f for qemu-devel@nongnu.org; Fri, 09 Nov 2007 12:45:46 -0500 Received: from smtp.citrix.com ([66.165.176.89]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IqXTp-00083O-L6 for qemu-devel@nongnu.org; Fri, 09 Nov 2007 12:17:22 -0500 Received: from implementation.famille.thibault.fr (host217-46-209-99.in-addr.btopenworld.com [217.46.209.99]) (authenticated bits=0) by smtp01.ad.xensource.com (8.13.1/8.13.1) with ESMTP id lA9HH2PZ012785 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 9 Nov 2007 09:17:04 -0800 Received: from samy by implementation.famille.thibault.fr with local (Exim 4.67) (envelope-from ) id 1IqXTa-0002pF-4S for qemu-devel@nongnu.org; Fri, 09 Nov 2007 18:17:02 +0100 Date: Fri, 9 Nov 2007 17:17:02 +0000 From: Samuel Thibault Message-ID: <20071109171702.GL3841@implementation.uk.xensource.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] [PATCH] partial reads/writes and block-raw.c Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org block-raw.c currently doesn't cope with partial reads and writes, here is a patch. Signed-off-by: Samuel Thibault Index: block-raw.c =================================================================== RCS file: /sources/qemu/qemu/block-raw.c,v retrieving revision 1.25 diff -u -p -r1.25 block-raw.c --- block-raw.c 20 Oct 2007 20:40:05 -0000 1.25 +++ block-raw.c 9 Nov 2007 17:16:35 -0000 @@ -142,7 +142,8 @@ static int raw_pread(BlockDriverState *b uint8_t *buf, int count) { BDRVRawState *s = bs->opaque; - int ret; + int ret, tries; + uint64_t done; ret = fd_open(bs); if (ret < 0) @@ -160,35 +161,32 @@ static int raw_pread(BlockDriverState *b } s->lseek_err_cnt=0; - ret = read(s->fd, buf, count); - if (ret == count) - goto label__raw_read__success; - - DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 - "] read failed %d : %d = %s\n", - s->fd, bs->filename, offset, buf, count, - bs->total_sectors, ret, errno, strerror(errno)); - - /* Try harder for CDrom. */ - if (bs->type == BDRV_TYPE_CDROM) { - lseek(s->fd, offset, SEEK_SET); - ret = read(s->fd, buf, count); - if (ret == count) - goto label__raw_read__success; - lseek(s->fd, offset, SEEK_SET); - ret = read(s->fd, buf, count); - if (ret == count) - goto label__raw_read__success; - - DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 - "] retry read failed %d : %d = %s\n", - s->fd, bs->filename, offset, buf, count, - bs->total_sectors, ret, errno, strerror(errno)); + tries = 0; + for (done = 0; done < count; done += ret) { + ret = read(s->fd, buf + done, count - done); + if (ret > 0) { + tries = 0; + } else if (ret == 0) { + DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 + "] read met end of file\n", + s->fd, bs->filename, offset, buf, count, + bs->total_sectors); + return -1; + } else { + /* Try harder for CDrom. */ + if (errno == EINTR || + (bs->type == BDRV_TYPE_CDROM && ++tries < 3)) { + ret = 0; + continue; + } + DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 + "] read failed %d : %d = %s\n", + s->fd, bs->filename, offset, buf, count, + bs->total_sectors, ret, errno, strerror(errno)); + return -1; + } } - -label__raw_read__success: - - return ret; + return count; } static int raw_pwrite(BlockDriverState *bs, int64_t offset, @@ -196,6 +194,7 @@ static int raw_pwrite(BlockDriverState * { BDRVRawState *s = bs->opaque; int ret; + uint64_t done; ret = fd_open(bs); if (ret < 0) @@ -213,18 +212,21 @@ static int raw_pwrite(BlockDriverState * } s->lseek_err_cnt = 0; - ret = write(s->fd, buf, count); - if (ret == count) - goto label__raw_write__success; - - DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 - "] write failed %d : %d = %s\n", - s->fd, bs->filename, offset, buf, count, - bs->total_sectors, ret, errno, strerror(errno)); - -label__raw_write__success: - - return ret; + for (done = 0; done < count; done += ret) { + ret = write(s->fd, buf + done, count - done); + if (ret == -1) { + if (errno == EINTR) { + ret = 0; + continue; + } + DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 + "] write failed %d : %d = %s\n", + s->fd, bs->filename, offset, buf, count, + bs->total_sectors, ret, errno, strerror(errno)); + return -1; + } + } + return count; } /***********************************************************/