* [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error.
@ 2009-01-15 10:12 Gleb Natapov
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 2/3] bdrv_write should not stop on partial write Gleb Natapov
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Gleb Natapov @ 2009-01-15 10:12 UTC (permalink / raw)
To: qemu-devel
And repeat last IDE command after VM restart.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
hw/ide.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/hw/ide.c b/hw/ide.c
index 7dd41f7..2d2cead 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -457,6 +457,8 @@ static inline int media_is_cd(IDEState *s)
#define BM_STATUS_DMAING 0x01
#define BM_STATUS_ERROR 0x02
#define BM_STATUS_INT 0x04
+#define BM_STATUS_DMA_RETRY 0x08
+#define BM_STATUS_PIO_RETRY 0x10
#define BM_CMD_START 0x01
#define BM_CMD_READ 0x08
@@ -488,6 +490,8 @@ typedef struct BMDMAState {
IDEState *ide_if;
BlockDriverCompletionFunc *dma_cb;
BlockDriverAIOCB *aiocb;
+ int64_t sector_num;
+ uint32_t nsector;
} BMDMAState;
typedef struct PCIIDEState {
@@ -498,6 +502,7 @@ typedef struct PCIIDEState {
} PCIIDEState;
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
+static void ide_dma_restart(IDEState *s);
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
static void padstr(char *str, const char *src, int len)
@@ -991,8 +996,13 @@ static void ide_sector_write(IDEState *s)
n = s->req_nb_sectors;
ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
if (ret != 0) {
- ide_rw_error(s);
- return;
+ if (ret == -ENOSPC) {
+ s->bmdma->ide_if = s;
+ s->bmdma->status |= BM_STATUS_PIO_RETRY;
+ vm_stop(0);
+ } else
+ ide_rw_error(s);
+ return;
}
s->nsector -= n;
@@ -1024,6 +1034,20 @@ static void ide_sector_write(IDEState *s)
}
}
+static void ide_dma_restart_cb(void *opaque, int running)
+{
+ BMDMAState *bm = opaque;
+ if (!running)
+ return;
+ if (bm->status & BM_STATUS_DMA_RETRY) {
+ bm->status &= ~BM_STATUS_DMA_RETRY;
+ ide_dma_restart(bm->ide_if);
+ } else if (bm->status & BM_STATUS_PIO_RETRY) {
+ bm->status &= ~BM_STATUS_PIO_RETRY;
+ ide_sector_write(bm->ide_if);
+ }
+}
+
static void ide_write_dma_cb(void *opaque, int ret)
{
BMDMAState *bm = opaque;
@@ -1032,8 +1056,12 @@ static void ide_write_dma_cb(void *opaque, int ret)
int64_t sector_num;
if (ret < 0) {
- ide_dma_error(s);
- return;
+ if (ret == -ENOSPC) {
+ bm->status |= BM_STATUS_DMA_RETRY;
+ vm_stop(0);
+ } else
+ ide_dma_error(s);
+ return;
}
n = s->io_buffer_size >> 9;
@@ -2849,11 +2877,24 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
bm->cur_prd_last = 0;
bm->cur_prd_addr = 0;
bm->cur_prd_len = 0;
+ bm->sector_num = ide_get_sector(s);
+ bm->nsector = s->nsector;
if (bm->status & BM_STATUS_DMAING) {
bm->dma_cb(bm, 0);
}
}
+static void ide_dma_restart(IDEState *s)
+{
+ BMDMAState *bm = s->bmdma;
+ ide_set_sector(s, bm->sector_num);
+ s->io_buffer_index = 0;
+ s->io_buffer_size = 0;
+ s->nsector = bm->nsector;
+ bm->cur_addr = bm->addr;
+ ide_dma_start(s, bm->dma_cb);
+}
+
static void ide_dma_cancel(BMDMAState *bm)
{
if (bm->status & BM_STATUS_DMAING) {
@@ -3043,6 +3084,7 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
d->ide_if[2 * i].bmdma = bm;
d->ide_if[2 * i + 1].bmdma = bm;
bm->pci_dev = (PCIIDEState *)pci_dev;
+ qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
@@ -3071,6 +3113,8 @@ static void pci_ide_save(QEMUFile* f, void *opaque)
qemu_put_8s(f, &bm->cmd);
qemu_put_8s(f, &bm->status);
qemu_put_be32s(f, &bm->addr);
+ qemu_put_sbe64s(f, &bm->sector_num);
+ qemu_put_be32s(f, &bm->nsector);
/* XXX: if a transfer is pending, we do not save it yet */
}
@@ -3105,6 +3149,8 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
qemu_get_8s(f, &bm->cmd);
qemu_get_8s(f, &bm->status);
qemu_get_be32s(f, &bm->addr);
+ qemu_get_sbe64s(f, &bm->sector_num);
+ qemu_get_be32s(f, &bm->nsector);
/* XXX: if a transfer is pending, we do not save it yet */
}
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 2/3] bdrv_write should not stop on partial write.
2009-01-15 10:12 [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Gleb Natapov
@ 2009-01-15 10:12 ` Gleb Natapov
2009-01-15 20:44 ` Anthony Liguori
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 3/3] Return -errno on write failure Gleb Natapov
2009-01-15 20:39 ` [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Anthony Liguori
2 siblings, 1 reply; 6+ messages in thread
From: Gleb Natapov @ 2009-01-15 10:12 UTC (permalink / raw)
To: qemu-devel
Should return real error instead.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
block.c | 27 ++++++++++++++-------------
1 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/block.c b/block.c
index 28d63d7..3250327 100644
--- a/block.c
+++ b/block.c
@@ -565,21 +565,22 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
if (bs->read_only)
return -EACCES;
if (drv->bdrv_pwrite) {
- int ret, len;
+ int ret, len, count = 0;
len = nb_sectors * 512;
- ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EIO;
- else {
- bs->wr_bytes += (unsigned) len;
- bs->wr_ops ++;
- return 0;
- }
- } else {
- return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
+ do {
+ ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len - count);
+ if (ret < 0) {
+ printf("bdrv_write ret=%d\n", ret);
+ return ret;
+ }
+ count += ret;
+ buf += ret;
+ } while (count != len);
+ bs->wr_bytes += (unsigned) len;
+ bs->wr_ops ++;
+ return 0;
}
+ return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
}
static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 3/3] Return -errno on write failure
2009-01-15 10:12 [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Gleb Natapov
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 2/3] bdrv_write should not stop on partial write Gleb Natapov
@ 2009-01-15 10:12 ` Gleb Natapov
2009-01-15 20:44 ` Anthony Liguori
2009-01-15 20:39 ` [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Anthony Liguori
2 siblings, 1 reply; 6+ messages in thread
From: Gleb Natapov @ 2009-01-15 10:12 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
block-raw-posix.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/block-raw-posix.c b/block-raw-posix.c
index 2fbb714..d17af0b 100644
--- a/block-raw-posix.c
+++ b/block-raw-posix.c
@@ -252,7 +252,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
ret = fd_open(bs);
if (ret < 0)
- return ret;
+ return -errno;
if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
++(s->lseek_err_cnt);
@@ -262,7 +262,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
s->fd, bs->filename, offset, buf, count,
bs->total_sectors, errno, strerror(errno));
}
- return -1;
+ return -EIO;
}
s->lseek_err_cnt = 0;
@@ -277,7 +277,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
label__raw_write__success:
- return ret;
+ return (ret < 0) ? -errno : ret;
}
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v2 3/3] Return -errno on write failure
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 3/3] Return -errno on write failure Gleb Natapov
@ 2009-01-15 20:44 ` Anthony Liguori
0 siblings, 0 replies; 6+ messages in thread
From: Anthony Liguori @ 2009-01-15 20:44 UTC (permalink / raw)
To: qemu-devel
Gleb Natapov wrote:
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
>
Applied. Thanks.
Regards,
Anthony Liguori
> ---
>
> block-raw-posix.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/block-raw-posix.c b/block-raw-posix.c
> index 2fbb714..d17af0b 100644
> --- a/block-raw-posix.c
> +++ b/block-raw-posix.c
> @@ -252,7 +252,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
>
> ret = fd_open(bs);
> if (ret < 0)
> - return ret;
> + return -errno;
>
> if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
> ++(s->lseek_err_cnt);
> @@ -262,7 +262,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
> s->fd, bs->filename, offset, buf, count,
> bs->total_sectors, errno, strerror(errno));
> }
> - return -1;
> + return -EIO;
> }
> s->lseek_err_cnt = 0;
>
> @@ -277,7 +277,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
>
> label__raw_write__success:
>
> - return ret;
> + return (ret < 0) ? -errno : ret;
> }
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error.
2009-01-15 10:12 [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Gleb Natapov
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 2/3] bdrv_write should not stop on partial write Gleb Natapov
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 3/3] Return -errno on write failure Gleb Natapov
@ 2009-01-15 20:39 ` Anthony Liguori
2 siblings, 0 replies; 6+ messages in thread
From: Anthony Liguori @ 2009-01-15 20:39 UTC (permalink / raw)
To: qemu-devel
Gleb Natapov wrote:
> And repeat last IDE command after VM restart.
>
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> ---
>
> hw/ide.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 files changed, 50 insertions(+), 4 deletions(-)
>
> diff --git a/hw/ide.c b/hw/ide.c
> index 7dd41f7..2d2cead 100644
> --- a/hw/ide.c
> +++ b/hw/ide.c
> @@ -457,6 +457,8 @@ static inline int media_is_cd(IDEState *s)
> #define BM_STATUS_DMAING 0x01
> #define BM_STATUS_ERROR 0x02
> #define BM_STATUS_INT 0x04
> +#define BM_STATUS_DMA_RETRY 0x08
> +#define BM_STATUS_PIO_RETRY 0x10
>
> #define BM_CMD_START 0x01
> #define BM_CMD_READ 0x08
> @@ -488,6 +490,8 @@ typedef struct BMDMAState {
> IDEState *ide_if;
> BlockDriverCompletionFunc *dma_cb;
> BlockDriverAIOCB *aiocb;
> + int64_t sector_num;
> + uint32_t nsector;
> } BMDMAState;
>
> typedef struct PCIIDEState {
> @@ -498,6 +502,7 @@ typedef struct PCIIDEState {
> } PCIIDEState;
>
> static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
> +static void ide_dma_restart(IDEState *s);
> static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
>
> static void padstr(char *str, const char *src, int len)
> @@ -991,8 +996,13 @@ static void ide_sector_write(IDEState *s)
> n = s->req_nb_sectors;
> ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
> if (ret != 0) {
> - ide_rw_error(s);
> - return;
> + if (ret == -ENOSPC) {
> + s->bmdma->ide_if = s;
> + s->bmdma->status |= BM_STATUS_PIO_RETRY;
> + vm_stop(0);
> + } else
> + ide_rw_error(s);
> + return;
> }
>
> s->nsector -= n;
> @@ -1024,6 +1034,20 @@ static void ide_sector_write(IDEState *s)
> }
> }
>
> +static void ide_dma_restart_cb(void *opaque, int running)
> +{
> + BMDMAState *bm = opaque;
> + if (!running)
> + return;
> + if (bm->status & BM_STATUS_DMA_RETRY) {
> + bm->status &= ~BM_STATUS_DMA_RETRY;
> + ide_dma_restart(bm->ide_if);
> + } else if (bm->status & BM_STATUS_PIO_RETRY) {
> + bm->status &= ~BM_STATUS_PIO_RETRY;
> + ide_sector_write(bm->ide_if);
> + }
> +}
> +
> static void ide_write_dma_cb(void *opaque, int ret)
> {
> BMDMAState *bm = opaque;
> @@ -1032,8 +1056,12 @@ static void ide_write_dma_cb(void *opaque, int ret)
> int64_t sector_num;
>
> if (ret < 0) {
> - ide_dma_error(s);
> - return;
> + if (ret == -ENOSPC) {
> + bm->status |= BM_STATUS_DMA_RETRY;
> + vm_stop(0);
> + } else
> + ide_dma_error(s);
> + return;
> }
>
> n = s->io_buffer_size >> 9;
> @@ -2849,11 +2877,24 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
> bm->cur_prd_last = 0;
> bm->cur_prd_addr = 0;
> bm->cur_prd_len = 0;
> + bm->sector_num = ide_get_sector(s);
> + bm->nsector = s->nsector;
> if (bm->status & BM_STATUS_DMAING) {
> bm->dma_cb(bm, 0);
> }
> }
>
> +static void ide_dma_restart(IDEState *s)
> +{
> + BMDMAState *bm = s->bmdma;
> + ide_set_sector(s, bm->sector_num);
> + s->io_buffer_index = 0;
> + s->io_buffer_size = 0;
> + s->nsector = bm->nsector;
> + bm->cur_addr = bm->addr;
> + ide_dma_start(s, bm->dma_cb);
> +}
> +
> static void ide_dma_cancel(BMDMAState *bm)
> {
> if (bm->status & BM_STATUS_DMAING) {
> @@ -3043,6 +3084,7 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
> d->ide_if[2 * i].bmdma = bm;
> d->ide_if[2 * i + 1].bmdma = bm;
> bm->pci_dev = (PCIIDEState *)pci_dev;
> + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
>
> register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
>
> @@ -3071,6 +3113,8 @@ static void pci_ide_save(QEMUFile* f, void *opaque)
> qemu_put_8s(f, &bm->cmd);
> qemu_put_8s(f, &bm->status);
> qemu_put_be32s(f, &bm->addr);
> + qemu_put_sbe64s(f, &bm->sector_num);
> + qemu_put_be32s(f, &bm->nsector);
>
If you're adding to the save/restore format, you have to increment the
version number.
Regards,
Anthony Liguori
> /* XXX: if a transfer is pending, we do not save it yet */
> }
>
> @@ -3105,6 +3149,8 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
> qemu_get_8s(f, &bm->cmd);
> qemu_get_8s(f, &bm->status);
> qemu_get_be32s(f, &bm->addr);
> + qemu_get_sbe64s(f, &bm->sector_num);
> + qemu_get_be32s(f, &bm->nsector);
> /* XXX: if a transfer is pending, we do not save it yet */
> }
>
>
>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-01-15 20:45 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-15 10:12 [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Gleb Natapov
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 2/3] bdrv_write should not stop on partial write Gleb Natapov
2009-01-15 20:44 ` Anthony Liguori
2009-01-15 10:12 ` [Qemu-devel] [PATCH v2 3/3] Return -errno on write failure Gleb Natapov
2009-01-15 20:44 ` Anthony Liguori
2009-01-15 20:39 ` [Qemu-devel] [PATCH v2 1/3] Stop VM on ENOSPC error Anthony Liguori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).