diff mbox

[2/3] ide: Set BSY bit during FLUSH

Message ID 1369827246-2802-3-git-send-email-kwolf@redhat.com
State New
Headers show

Commit Message

Kevin Wolf May 29, 2013, 11:34 a.m. UTC
From: Andreas Färber <afaerber@suse.de>

The implementation of the ATA FLUSH command invokes a flush at the block
layer, which may on raw files on POSIX entail a synchronous fdatasync().
This may in some cases take so long that the SLES 11 SP1 guest driver
reports I/O errors and filesystems get corrupted or remounted read-only.

Avoid this by setting BUSY_STAT, so that the guest is made aware we are
in the middle of an operation and no ATA commands are attempted to be
processed concurrently.

Addresses BNC#637297.

Suggested-by: Gonglei (Arei) <arei.gonglei@huawei.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Andreas Färber May 29, 2013, 11:50 a.m. UTC | #1
Am 29.05.2013 13:34, schrieb Kevin Wolf:
> From: Andreas Färber <afaerber@suse.de>
> 
> The implementation of the ATA FLUSH command invokes a flush at the block
> layer, which may on raw files on POSIX entail a synchronous fdatasync().
> This may in some cases take so long that the SLES 11 SP1 guest driver
> reports I/O errors and filesystems get corrupted or remounted read-only.
> 
> Avoid this by setting BUSY_STAT, so that the guest is made aware we are
> in the middle of an operation and no ATA commands are attempted to be
> processed concurrently.
> 
> Addresses BNC#637297.
> 
> Suggested-by: Gonglei (Arei) <arei.gonglei@huawei.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  hw/ide/core.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index c7a8041..bf1ff18 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -795,6 +795,8 @@ static void ide_flush_cb(void *opaque, int ret)
>  {
>      IDEState *s = opaque;
>  
> +    s->status &= ~BUSY_STAT;
> +
>      if (ret < 0) {
>          /* XXX: What sector number to set here? */
>          if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {

Didn't you want this hunk to be dropped?

But thanks for picking the patch up already.

Andreas

> @@ -814,6 +816,7 @@ void ide_flush_cache(IDEState *s)
>          return;
>      }
>  
> +    s->status |= BUSY_STAT;
>      bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
>      bdrv_aio_flush(s->bs, ide_flush_cb, s);
>  }
>
Kevin Wolf May 29, 2013, 12:46 p.m. UTC | #2
Am 29.05.2013 um 13:50 hat Andreas Färber geschrieben:
> Am 29.05.2013 13:34, schrieb Kevin Wolf:
> > From: Andreas Färber <afaerber@suse.de>
> > 
> > The implementation of the ATA FLUSH command invokes a flush at the block
> > layer, which may on raw files on POSIX entail a synchronous fdatasync().
> > This may in some cases take so long that the SLES 11 SP1 guest driver
> > reports I/O errors and filesystems get corrupted or remounted read-only.
> > 
> > Avoid this by setting BUSY_STAT, so that the guest is made aware we are
> > in the middle of an operation and no ATA commands are attempted to be
> > processed concurrently.
> > 
> > Addresses BNC#637297.
> > 
> > Suggested-by: Gonglei (Arei) <arei.gonglei@huawei.com>
> > Signed-off-by: Andreas Färber <afaerber@suse.de>
> > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> > ---
> >  hw/ide/core.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/hw/ide/core.c b/hw/ide/core.c
> > index c7a8041..bf1ff18 100644
> > --- a/hw/ide/core.c
> > +++ b/hw/ide/core.c
> > @@ -795,6 +795,8 @@ static void ide_flush_cb(void *opaque, int ret)
> >  {
> >      IDEState *s = opaque;
> >  
> > +    s->status &= ~BUSY_STAT;
> > +
> >      if (ret < 0) {
> >          /* XXX: What sector number to set here? */
> >          if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {
> 
> Didn't you want this hunk to be dropped?
> 
> But thanks for picking the patch up already.

Ah, right, dropped it now. Thanks.

Kevin
diff mbox

Patch

diff --git a/hw/ide/core.c b/hw/ide/core.c
index c7a8041..bf1ff18 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -795,6 +795,8 @@  static void ide_flush_cb(void *opaque, int ret)
 {
     IDEState *s = opaque;
 
+    s->status &= ~BUSY_STAT;
+
     if (ret < 0) {
         /* XXX: What sector number to set here? */
         if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {
@@ -814,6 +816,7 @@  void ide_flush_cache(IDEState *s)
         return;
     }
 
+    s->status |= BUSY_STAT;
     bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
     bdrv_aio_flush(s->bs, ide_flush_cb, s);
 }