qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RESEND] file-posix: Handle `EINVAL` fallocate return value
@ 2020-07-17 13:56 antoine.damhet
  2020-07-20 14:07 ` Kevin Wolf
  0 siblings, 1 reply; 4+ messages in thread
From: antoine.damhet @ 2020-07-17 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: antoine.damhet, Kevin Wolf, open list:raw, Max Reitz

From: Antoine Damhet <antoine.damhet@blade-group.com>

The `detect-zeroes=unmap` option may issue unaligned
`FALLOC_FL_PUNCH_HOLE` requests, raw block devices can (and will) return
`EINVAL`, qemu should then write the zeroes to the blockdev instead of
issuing an `IO_ERROR`.

Signed-off-by: Antoine Damhet <antoine.damhet@blade-group.com>
---

I am resending this patch because:
1. I sent the first version from the wrong email address
2. I forgot to send it to the devel mailing list

Please forgive me for the inconvenience.

 block/file-posix.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 8067e238cb..b2fabcc1b8 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1620,7 +1620,11 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
 #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
     int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
                            aiocb->aio_offset, aiocb->aio_nbytes);
-    if (ret != -ENOTSUP) {
+    switch (ret) {
+    case -ENOTSUP:
+    case -EINVAL:
+        break;
+    default:
         return ret;
     }
 #endif
-- 
2.27.0



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH RESEND] file-posix: Handle `EINVAL` fallocate return value
  2020-07-17 13:56 [PATCH RESEND] file-posix: Handle `EINVAL` fallocate return value antoine.damhet
@ 2020-07-20 14:07 ` Kevin Wolf
  2020-07-20 15:37   ` Antoine Damhet
  0 siblings, 1 reply; 4+ messages in thread
From: Kevin Wolf @ 2020-07-20 14:07 UTC (permalink / raw)
  To: antoine.damhet; +Cc: qemu-devel, open list:raw, Max Reitz

Am 17.07.2020 um 15:56 hat antoine.damhet@blade-group.com geschrieben:
> From: Antoine Damhet <antoine.damhet@blade-group.com>
> 
> The `detect-zeroes=unmap` option may issue unaligned
> `FALLOC_FL_PUNCH_HOLE` requests, raw block devices can (and will) return
> `EINVAL`, qemu should then write the zeroes to the blockdev instead of
> issuing an `IO_ERROR`.
> 
> Signed-off-by: Antoine Damhet <antoine.damhet@blade-group.com>

Do you have a simple reproducer for this? I tried it with something like
this (also with a LV instead of loop, but it didn't really make a
difference):

$ ./qemu-io -c 'write -P 0 42 1234' --image-opts driver=host_device,filename=/dev/loop0,cache.direct=on,detect-zeroes=on
wrote 1234/1234 bytes at offset 42
1.205 KiB, 1 ops; 00.00 sec (2.021 MiB/sec and 1717.5697 ops/sec)

So I don't seem to run into an error.

> diff --git a/block/file-posix.c b/block/file-posix.c
> index 8067e238cb..b2fabcc1b8 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1620,7 +1620,11 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
>  #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
>      int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
>                             aiocb->aio_offset, aiocb->aio_nbytes);
> -    if (ret != -ENOTSUP) {
> +    switch (ret) {
> +    case -ENOTSUP:
> +    case -EINVAL:
> +        break;
> +    default:
>          return ret;
>      }
>  #endif

This means that we fall back to BLKZEROOUT in case of -EINVAL. Does this
return a better error code in the relevant cases, or did you just happen
to test a case where it was skipped or returned -ENOTSUP?

Kevin



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH RESEND] file-posix: Handle `EINVAL` fallocate return value
  2020-07-20 14:07 ` Kevin Wolf
@ 2020-07-20 15:37   ` Antoine Damhet
  2020-07-21 14:21     ` Kevin Wolf
  0 siblings, 1 reply; 4+ messages in thread
From: Antoine Damhet @ 2020-07-20 15:37 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, open list:raw, Max Reitz

[-- Attachment #1: Type: text/plain, Size: 2591 bytes --]

On Mon, Jul 20, 2020 at 04:07:26PM +0200, Kevin Wolf wrote:
> Am 17.07.2020 um 15:56 hat antoine.damhet@blade-group.com geschrieben:
> > From: Antoine Damhet <antoine.damhet@blade-group.com>
> > 
> > The `detect-zeroes=unmap` option may issue unaligned
> > `FALLOC_FL_PUNCH_HOLE` requests, raw block devices can (and will) return
> > `EINVAL`, qemu should then write the zeroes to the blockdev instead of
> > issuing an `IO_ERROR`.
> > 
> > Signed-off-by: Antoine Damhet <antoine.damhet@blade-group.com>
> 
> Do you have a simple reproducer for this? I tried it with something like
> this (also with a LV instead of loop, but it didn't really make a
> difference):
> 
> $ ./qemu-io -c 'write -P 0 42 1234' --image-opts driver=host_device,filename=/dev/loop0,cache.direct=on,detect-zeroes=on
> wrote 1234/1234 bytes at offset 42
> 1.205 KiB, 1 ops; 00.00 sec (2.021 MiB/sec and 1717.5697 ops/sec)
> 
> So I don't seem to run into an error.

```
$ qemu-io -c 'write -P 0 42 1234' --image-opts driver=host_device,filename=/dev/loop0,detect-zeroes=unmap
write failed: Invalid argument
```

This seems do do the trick :) (We triggered the bug with Windows 10
guests and with an iSCSI drive so it was hardly a simple reproducer).

> 
> > diff --git a/block/file-posix.c b/block/file-posix.c
> > index 8067e238cb..b2fabcc1b8 100644
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -1620,7 +1620,11 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
> >  #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
> >      int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> >                             aiocb->aio_offset, aiocb->aio_nbytes);
> > -    if (ret != -ENOTSUP) {
> > +    switch (ret) {
> > +    case -ENOTSUP:
> > +    case -EINVAL:
> > +        break;
> > +    default:
> >          return ret;
> >      }
> >  #endif
> 
> This means that we fall back to BLKZEROOUT in case of -EINVAL. Does this
> return a better error code in the relevant cases, or did you just happen
> to test a case where it was skipped or returned -ENOTSUP?

I guess I misinterpreted the comment before calling
`handle_aiocb_write_zeroes`.

The codepath is:
* handle_aiocb_write_zeroes_unmap -> handle_aiocb_write_zeroes -> handle_aiocb_write_zeroes_block

In witch the code will return `-ENOSTUP` (`!s->has_write_zeroes`) and
never fall back to `BLKZEROOUT`.

So it's working as I expected but now I am unsure that my fix is the
right thing to do, what do you think ?

> 
> Kevin
> 
> 

-- 
Antoine 'xdbob' Damhet

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH RESEND] file-posix: Handle `EINVAL` fallocate return value
  2020-07-20 15:37   ` Antoine Damhet
@ 2020-07-21 14:21     ` Kevin Wolf
  0 siblings, 0 replies; 4+ messages in thread
From: Kevin Wolf @ 2020-07-21 14:21 UTC (permalink / raw)
  To: Antoine Damhet; +Cc: qemu-devel, open list:raw, Max Reitz

[-- Attachment #1: Type: text/plain, Size: 3297 bytes --]

Am 20.07.2020 um 17:37 hat Antoine Damhet geschrieben:
> On Mon, Jul 20, 2020 at 04:07:26PM +0200, Kevin Wolf wrote:
> > Am 17.07.2020 um 15:56 hat antoine.damhet@blade-group.com geschrieben:
> > > From: Antoine Damhet <antoine.damhet@blade-group.com>
> > > 
> > > The `detect-zeroes=unmap` option may issue unaligned
> > > `FALLOC_FL_PUNCH_HOLE` requests, raw block devices can (and will) return
> > > `EINVAL`, qemu should then write the zeroes to the blockdev instead of
> > > issuing an `IO_ERROR`.
> > > 
> > > Signed-off-by: Antoine Damhet <antoine.damhet@blade-group.com>
> > 
> > Do you have a simple reproducer for this? I tried it with something like
> > this (also with a LV instead of loop, but it didn't really make a
> > difference):
> > 
> > $ ./qemu-io -c 'write -P 0 42 1234' --image-opts driver=host_device,filename=/dev/loop0,cache.direct=on,detect-zeroes=on
> > wrote 1234/1234 bytes at offset 42
> > 1.205 KiB, 1 ops; 00.00 sec (2.021 MiB/sec and 1717.5697 ops/sec)
> > 
> > So I don't seem to run into an error.
> 
> ```
> $ qemu-io -c 'write -P 0 42 1234' --image-opts driver=host_device,filename=/dev/loop0,detect-zeroes=unmap
> write failed: Invalid argument
> ```
> 
> This seems do do the trick :) (We triggered the bug with Windows 10
> guests and with an iSCSI drive so it was hardly a simple reproducer).

Oops, I made a stupid mistake with the detect-zeroes syntax there. :-)

So you actually need non-O_DIRECT. Okay, I can reproduce with your line.

> > > diff --git a/block/file-posix.c b/block/file-posix.c
> > > index 8067e238cb..b2fabcc1b8 100644
> > > --- a/block/file-posix.c
> > > +++ b/block/file-posix.c
> > > @@ -1620,7 +1620,11 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
> > >  #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
> > >      int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> > >                             aiocb->aio_offset, aiocb->aio_nbytes);
> > > -    if (ret != -ENOTSUP) {
> > > +    switch (ret) {
> > > +    case -ENOTSUP:
> > > +    case -EINVAL:
> > > +        break;
> > > +    default:
> > >          return ret;
> > >      }
> > >  #endif
> > 
> > This means that we fall back to BLKZEROOUT in case of -EINVAL. Does this
> > return a better error code in the relevant cases, or did you just happen
> > to test a case where it was skipped or returned -ENOTSUP?
> 
> I guess I misinterpreted the comment before calling
> `handle_aiocb_write_zeroes`.
> 
> The codepath is:
> * handle_aiocb_write_zeroes_unmap -> handle_aiocb_write_zeroes -> handle_aiocb_write_zeroes_block
> 
> In witch the code will return `-ENOSTUP` (`!s->has_write_zeroes`) and
> never fall back to `BLKZEROOUT`.
> 
> So it's working as I expected but now I am unsure that my fix is the
> right thing to do, what do you think ?

It's obviously fixing something for you, though it might not be as
complete as we'd like. Maybe we would just need to do the same thing in
more places, though ideally we would need reproducers for each of them.

I just noticed that handle_aiocb_write_zeroes() already turns EINVAL
into ENOTSUP, so your change is not unprecedented.

I'll just apply your patch for now, and we can always fix more cases on
top of it.

Kevin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-07-21 14:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-17 13:56 [PATCH RESEND] file-posix: Handle `EINVAL` fallocate return value antoine.damhet
2020-07-20 14:07 ` Kevin Wolf
2020-07-20 15:37   ` Antoine Damhet
2020-07-21 14:21     ` Kevin Wolf

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).