block-raw.c currently doesn't cope with partial reads and writes, here is a patch.
Signed-off-by: Samuel Thibault <[EMAIL PROTECTED]> 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; } /***********************************************************/