Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-27 Thread Vladimir Sementsov-Ogievskiy

26.08.2020 16:51, David Edmondson wrote:

+  file-systems with slow allocation.
+
+  Supported options:
+
+  .. program:: preallocate
+  .. option:: prealloc-align
+
+On preallocation, align file length to this number, default 1M.

*the file length

As for “number”...  Well, it is a number.  But “value” might fit better.
  Or “length (in bytes)”?

Isn't it really:

"On preallocation, ensure that the file length is aligned to a multiple
of this value, default 1M."



Sounds good, thanks!


--
Best regards,
Vladimir



Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-26 Thread David Edmondson
On Tuesday, 2020-08-25 at 17:11:34 +02, Max Reitz wrote:

> On 21.08.20 16:11, Vladimir Sementsov-Ogievskiy wrote:
>> It's intended to be inserted between format and protocol nodes to
>> preallocate additional space (expanding protocol file) on writes
>> crossing EOF. It improves performance for file-systems with slow
>> allocation.
>> 
>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>> ---
>>  docs/system/qemu-block-drivers.rst.inc |  26 +++
>>  qapi/block-core.json   |  20 +-
>>  block/preallocate.c| 291 +
>>  block/Makefile.objs|   1 +
>>  4 files changed, 337 insertions(+), 1 deletion(-)
>>  create mode 100644 block/preallocate.c
>
> Looks good to me in essence.  Besides minor details, I wonder most about
> whether truncating the file on close can be safe, but more about that below.
>
>> diff --git a/docs/system/qemu-block-drivers.rst.inc 
>> b/docs/system/qemu-block-drivers.rst.inc
>> index b052a6d14e..5e8a35c571 100644
>> --- a/docs/system/qemu-block-drivers.rst.inc
>> +++ b/docs/system/qemu-block-drivers.rst.inc
>> @@ -952,3 +952,29 @@ on host and see if there are locks held by the QEMU 
>> process on the image file.
>>  More than one byte could be locked by the QEMU instance, each byte of which
>>  reflects a particular permission that is acquired or protected by the 
>> running
>>  block driver.
>> +
>> +Filter drivers
>> +~~
>> +
>> +QEMU supports several filter drivers, which don't store any data, but do 
>> some
>
> s/do/perform/
>
>> +additional tasks, hooking io requests.
>> +
>> +.. program:: filter-drivers
>> +.. option:: preallocate
>> +
>> +  Preallocate filter driver is intended to be inserted between format
>
> *The preallocate filter driver
>
>> +  and protocol nodes and does preallocation of some additional space
>
> I’d simplify this as s/does preallocation of/preallocates/
>
>> +  (expanding the protocol file) on write. It may be used for
>
> I’d complicate this as s/on write/when writing past the file’s end/, or
> “when data is written to the file after its end”, or at least “on
> post-EOF writes”.
>
> Maybe also s/It may be used for/This can be useful for/?
>
>> +  file-systems with slow allocation.
>> +
>> +  Supported options:
>> +
>> +  .. program:: preallocate
>> +  .. option:: prealloc-align
>> +
>> +On preallocation, align file length to this number, default 1M.
>
> *the file length
>
> As for “number”...  Well, it is a number.  But “value” might fit better.
>  Or “length (in bytes)”?

Isn't it really:

"On preallocation, ensure that the file length is aligned to a multiple
of this value, default 1M."

?

>> +
>> +  .. program:: preallocate
>> +  .. option:: prealloc-size
>> +
>> +How much to preallocate, default 128M.
>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>> index 197bdc1c36..b40448063b 100644
>> --- a/qapi/block-core.json
>> +++ b/qapi/block-core.json
>> @@ -2805,7 +2805,7 @@
>>  'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 
>> 'ftps',
>>  'gluster', 'host_cdrom', 'host_device', 'http', 'https', 
>> 'iscsi',
>>  'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 
>> 'parallels',
>> -'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
>> +'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
>>  { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
>>  'sheepdog',
>>  'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
>> @@ -3074,6 +3074,23 @@
>>'data': { 'aes': 'QCryptoBlockOptionsQCow',
>>  'luks': 'QCryptoBlockOptionsLUKS'} }
>>  
>> +##
>> +# @BlockdevOptionsPreallocate:
>> +#
>> +# Filter driver intended to be inserted between format and protocol node
>> +# and do preallocation in protocol node on write.
>> +#
>> +# @prealloc-align: on preallocation, align file length to this number,
>> +# default 1048576 (1M)
>
> Speaking of alignment, this second line isn’t properly aligned.
>
>> +#
>> +# @prealloc-size: how much to preallocate, default 134217728 (128M)
>> +#
>> +# Since: 5.2
>> +##
>> +{ 'struct': 'BlockdevOptionsPreallocate',
>> +  'base': 'BlockdevOptionsGenericFormat',
>> +  'data': { '*prealloc-align': 'int', '*prealloc-size': 'int' } }
>> +
>>  ##
>>  # @BlockdevOptionsQcow2:
>>  #
>> @@ -3979,6 +3996,7 @@
>>'null-co':'BlockdevOptionsNull',
>>'nvme':   'BlockdevOptionsNVMe',
>>'parallels':  'BlockdevOptionsGenericFormat',
>> +  'preallocate':'BlockdevOptionsPreallocate',
>>'qcow2':  'BlockdevOptionsQcow2',
>>'qcow':   'BlockdevOptionsQcow',
>>'qed':'BlockdevOptionsGenericCOWFormat',
>> diff --git a/block/preallocate.c b/block/preallocate.c
>> new file mode 100644
>> index 00..bdf54dbd2f
>> --- /dev/null
>> +++ b/block/preallocate.c
>> @@ -0,0 +1,291 @@
>> +/*
>> + * preallocate filter driver

Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-26 Thread Vladimir Sementsov-Ogievskiy

26.08.2020 12:58, Max Reitz wrote:

On 26.08.20 11:15, Vladimir Sementsov-Ogievskiy wrote:

26.08.2020 11:52, Max Reitz wrote:

On 26.08.20 08:49, Vladimir Sementsov-Ogievskiy wrote:

25.08.2020 18:11, Max Reitz wrote:

On 21.08.20 16:11, Vladimir Sementsov-Ogievskiy wrote:

It's intended to be inserted between format and protocol nodes to
preallocate additional space (expanding protocol file) on writes
crossing EOF. It improves performance for file-systems with slow
allocation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
    docs/system/qemu-block-drivers.rst.inc |  26 +++
    qapi/block-core.json   |  20 +-
    block/preallocate.c    | 291
+
    block/Makefile.objs    |   1 +
    4 files changed, 337 insertions(+), 1 deletion(-)
    create mode 100644 block/preallocate.c


[...]


diff --git a/block/preallocate.c b/block/preallocate.c
new file mode 100644
index 00..bdf54dbd2f
--- /dev/null
+++ b/block/preallocate.c
@@ -0,0 +1,291 @@
+/*
+ * preallocate filter driver
+ *
+ * The driver performs preallocate operation: it is injected above
+ * some node, and before each write over EOF it does additional
preallocating
+ * write-zeroes request.
+ *
+ * Copyright (c) 2020 Virtuozzo International GmbH.
+ *
+ * Author:
+ *  Sementsov-Ogievskiy Vladimir 
+ *
+ * This program is free software; you can redistribute it and/or
modify
+ * it under the terms of the GNU General Public License as
published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qemu/units.h"
+#include "block/block_int.h"
+
+
+typedef struct BDRVPreallocateState {
+    int64_t prealloc_size;
+    int64_t prealloc_align;
+
+    /*
+ * Filter is started as not-active, so it doesn't do any
preallocations nor
+ * requires BLK_PERM_RESIZE on its child. This is needed to
create filter
+ * above another node-child and then do bdrv_replace_node to
insert the
+ * filter.


A bit weird, but seems fair.  It’s basically just a cache for whether
this node has a writer on it or not.

Apart from the weirdness, I don’t understand the “another node-child”.
Say you have “format” -> “proto”, and then you want to insert
“prealloc”.  Wouldn’t you blockdev-add prealloc,file=proto and then
blockdev-replace format.file=prealloc?


Yes something like this. Actually, I'm about inserting the filter
automatically from block layer code, but your reasoning is about same
thing and is better.


So what is that “other node-child”?


Hmm, just my misleading wording. At least '-' in wrong place. Just
"other node child", or "child of another node"..


OK.


+ *
+ * Filter becomes active the first time it detects that its
parents have
+ * BLK_PERM_RESIZE on it.
+ * Filter becomes active forever: it doesn't lose active status
if parents
+ * lose BLK_PERM_RESIZE, otherwise we'll not be able to shrink
the file on
+ * filter close.


Oh, the file is shrunk?  That wasn’t clear from the documentation.

Hm.  Seems like useful behavior.  I just wonder if keeping the
permission around indefinitely makes sense.  Why not just truncate it
when the permission is revoked?


How? Parent is closed earlier, so on close we will not have the
permission. So, we force-keep the permission up to our close().


I thought that preallocate_child_perm() would be invoked when the parent
is detached, so we could do the truncate there, before relinquishing
preallocate’s RESIZE permission.



Hmm, I can check it. I just a bit afraid of doing something serious like
truncation in .bdrv_child_perm() handler, which doesn't seem to imply
such usage.


I’m a bit conflicted.  On one hand, I share your concern.  On the other,
I find it completely reasonable that drivers might want to do I/O when
permissions change.

Usually, this is done as part of reopen, like in qcow2 when a drive
changes from R/W to RO and caches need to be flushed.  But I actually
think it makes more sense as part of the permission system, because of
course a reopen is not the only time when permissions can change.

So that would be another alternative, to implement
.bdrv_reopen_prepare(), and to check reopen_state->perm there.  If
RESIZE is about to go away, then we truncate.  We could keep track of
whether we did any preallocations after the last such truncate, and if
we did, do another truncate on close.

This would cover reopen at least.  Seems 

Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-26 Thread Max Reitz
On 26.08.20 11:15, Vladimir Sementsov-Ogievskiy wrote:
> 26.08.2020 11:52, Max Reitz wrote:
>> On 26.08.20 08:49, Vladimir Sementsov-Ogievskiy wrote:
>>> 25.08.2020 18:11, Max Reitz wrote:
 On 21.08.20 16:11, Vladimir Sementsov-Ogievskiy wrote:
> It's intended to be inserted between format and protocol nodes to
> preallocate additional space (expanding protocol file) on writes
> crossing EOF. It improves performance for file-systems with slow
> allocation.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>    docs/system/qemu-block-drivers.rst.inc |  26 +++
>    qapi/block-core.json   |  20 +-
>    block/preallocate.c    | 291
> +
>    block/Makefile.objs    |   1 +
>    4 files changed, 337 insertions(+), 1 deletion(-)
>    create mode 100644 block/preallocate.c
>>
>> [...]
>>
> diff --git a/block/preallocate.c b/block/preallocate.c
> new file mode 100644
> index 00..bdf54dbd2f
> --- /dev/null
> +++ b/block/preallocate.c
> @@ -0,0 +1,291 @@
> +/*
> + * preallocate filter driver
> + *
> + * The driver performs preallocate operation: it is injected above
> + * some node, and before each write over EOF it does additional
> preallocating
> + * write-zeroes request.
> + *
> + * Copyright (c) 2020 Virtuozzo International GmbH.
> + *
> + * Author:
> + *  Sementsov-Ogievskiy Vladimir 
> + *
> + * This program is free software; you can redistribute it and/or
> modify
> + * it under the terms of the GNU General Public License as
> published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see
> .
> + */
> +
> +#include "qemu/osdep.h"
> +
> +#include "qapi/error.h"
> +#include "qemu/module.h"
> +#include "qemu/option.h"
> +#include "qemu/units.h"
> +#include "block/block_int.h"
> +
> +
> +typedef struct BDRVPreallocateState {
> +    int64_t prealloc_size;
> +    int64_t prealloc_align;
> +
> +    /*
> + * Filter is started as not-active, so it doesn't do any
> preallocations nor
> + * requires BLK_PERM_RESIZE on its child. This is needed to
> create filter
> + * above another node-child and then do bdrv_replace_node to
> insert the
> + * filter.

 A bit weird, but seems fair.  It’s basically just a cache for whether
 this node has a writer on it or not.

 Apart from the weirdness, I don’t understand the “another node-child”.
 Say you have “format” -> “proto”, and then you want to insert
 “prealloc”.  Wouldn’t you blockdev-add prealloc,file=proto and then
 blockdev-replace format.file=prealloc?
>>>
>>> Yes something like this. Actually, I'm about inserting the filter
>>> automatically from block layer code, but your reasoning is about same
>>> thing and is better.
>>>
 So what is that “other node-child”?
>>>
>>> Hmm, just my misleading wording. At least '-' in wrong place. Just
>>> "other node child", or "child of another node"..
>>
>> OK.
>>
> + *
> + * Filter becomes active the first time it detects that its
> parents have
> + * BLK_PERM_RESIZE on it.
> + * Filter becomes active forever: it doesn't lose active status
> if parents
> + * lose BLK_PERM_RESIZE, otherwise we'll not be able to shrink
> the file on
> + * filter close.

 Oh, the file is shrunk?  That wasn’t clear from the documentation.

 Hm.  Seems like useful behavior.  I just wonder if keeping the
 permission around indefinitely makes sense.  Why not just truncate it
 when the permission is revoked?
>>>
>>> How? Parent is closed earlier, so on close we will not have the
>>> permission. So, we force-keep the permission up to our close().
>>
>> I thought that preallocate_child_perm() would be invoked when the parent
>> is detached, so we could do the truncate there, before relinquishing
>> preallocate’s RESIZE permission.
>>
> 
> Hmm, I can check it. I just a bit afraid of doing something serious like
> truncation in .bdrv_child_perm() handler, which doesn't seem to imply
> such usage.

I’m a bit conflicted.  On one hand, I share your concern.  On the other,
I find it completely reasonable that drivers might want to do I/O when
permissions change.

Usually, this is done as part of 

Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-26 Thread Vladimir Sementsov-Ogievskiy

26.08.2020 11:52, Max Reitz wrote:

On 26.08.20 08:49, Vladimir Sementsov-Ogievskiy wrote:

25.08.2020 18:11, Max Reitz wrote:

On 21.08.20 16:11, Vladimir Sementsov-Ogievskiy wrote:

It's intended to be inserted between format and protocol nodes to
preallocate additional space (expanding protocol file) on writes
crossing EOF. It improves performance for file-systems with slow
allocation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
   docs/system/qemu-block-drivers.rst.inc |  26 +++
   qapi/block-core.json   |  20 +-
   block/preallocate.c    | 291 +
   block/Makefile.objs    |   1 +
   4 files changed, 337 insertions(+), 1 deletion(-)
   create mode 100644 block/preallocate.c


[...]


diff --git a/block/preallocate.c b/block/preallocate.c
new file mode 100644
index 00..bdf54dbd2f
--- /dev/null
+++ b/block/preallocate.c
@@ -0,0 +1,291 @@
+/*
+ * preallocate filter driver
+ *
+ * The driver performs preallocate operation: it is injected above
+ * some node, and before each write over EOF it does additional
preallocating
+ * write-zeroes request.
+ *
+ * Copyright (c) 2020 Virtuozzo International GmbH.
+ *
+ * Author:
+ *  Sementsov-Ogievskiy Vladimir 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qemu/units.h"
+#include "block/block_int.h"
+
+
+typedef struct BDRVPreallocateState {
+    int64_t prealloc_size;
+    int64_t prealloc_align;
+
+    /*
+ * Filter is started as not-active, so it doesn't do any
preallocations nor
+ * requires BLK_PERM_RESIZE on its child. This is needed to
create filter
+ * above another node-child and then do bdrv_replace_node to
insert the
+ * filter.


A bit weird, but seems fair.  It’s basically just a cache for whether
this node has a writer on it or not.

Apart from the weirdness, I don’t understand the “another node-child”.
Say you have “format” -> “proto”, and then you want to insert
“prealloc”.  Wouldn’t you blockdev-add prealloc,file=proto and then
blockdev-replace format.file=prealloc?


Yes something like this. Actually, I'm about inserting the filter
automatically from block layer code, but your reasoning is about same
thing and is better.


So what is that “other node-child”?


Hmm, just my misleading wording. At least '-' in wrong place. Just
"other node child", or "child of another node"..


OK.


+ *
+ * Filter becomes active the first time it detects that its
parents have
+ * BLK_PERM_RESIZE on it.
+ * Filter becomes active forever: it doesn't lose active status
if parents
+ * lose BLK_PERM_RESIZE, otherwise we'll not be able to shrink
the file on
+ * filter close.


Oh, the file is shrunk?  That wasn’t clear from the documentation.

Hm.  Seems like useful behavior.  I just wonder if keeping the
permission around indefinitely makes sense.  Why not just truncate it
when the permission is revoked?


How? Parent is closed earlier, so on close we will not have the
permission. So, we force-keep the permission up to our close().


I thought that preallocate_child_perm() would be invoked when the parent
is detached, so we could do the truncate there, before relinquishing
preallocate’s RESIZE permission.



Hmm, I can check it. I just a bit afraid of doing something serious like 
truncation in .bdrv_child_perm() handler, which doesn't seem to imply such 
usage.




+static void preallocate_close(BlockDriverState *bs)
+{
+    BDRVPreallocateState *s = bs->opaque;
+
+    if (s->active && s->data_end >= 0 &&
+    bdrv_getlength(bs->file->bs) > s->data_end)
+    {
+    bdrv_truncate(bs->file, s->data_end, true,
PREALLOC_MODE_OFF, 0, NULL);


Now that I think more about it...  What if there are other writers on
bs->file?  This may throw data away.


Good point. Actually, if bs->file has other writing parents, the logic
of the filter
around "data_end" is broken. So we must unshare WRITE and RESIZE
permissions.


That’s certainly a heavy hammer, but it’d work.


  Maybe BDS.wr_highest_offset can
help to make a better call?


Anyway, we'll have to use wr_highest_offset of the filter not the child
node
(in the child wr_highest_offset will track preallocations as well),


That’s true.


so we want to unshare WRITE/RESIZE 

Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-26 Thread Max Reitz
On 26.08.20 08:49, Vladimir Sementsov-Ogievskiy wrote:
> 25.08.2020 18:11, Max Reitz wrote:
>> On 21.08.20 16:11, Vladimir Sementsov-Ogievskiy wrote:
>>> It's intended to be inserted between format and protocol nodes to
>>> preallocate additional space (expanding protocol file) on writes
>>> crossing EOF. It improves performance for file-systems with slow
>>> allocation.
>>>
>>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>>> ---
>>>   docs/system/qemu-block-drivers.rst.inc |  26 +++
>>>   qapi/block-core.json   |  20 +-
>>>   block/preallocate.c    | 291 +
>>>   block/Makefile.objs    |   1 +
>>>   4 files changed, 337 insertions(+), 1 deletion(-)
>>>   create mode 100644 block/preallocate.c

[...]

>>> diff --git a/block/preallocate.c b/block/preallocate.c
>>> new file mode 100644
>>> index 00..bdf54dbd2f
>>> --- /dev/null
>>> +++ b/block/preallocate.c
>>> @@ -0,0 +1,291 @@
>>> +/*
>>> + * preallocate filter driver
>>> + *
>>> + * The driver performs preallocate operation: it is injected above
>>> + * some node, and before each write over EOF it does additional
>>> preallocating
>>> + * write-zeroes request.
>>> + *
>>> + * Copyright (c) 2020 Virtuozzo International GmbH.
>>> + *
>>> + * Author:
>>> + *  Sementsov-Ogievskiy Vladimir 
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program. If not, see .
>>> + */
>>> +
>>> +#include "qemu/osdep.h"
>>> +
>>> +#include "qapi/error.h"
>>> +#include "qemu/module.h"
>>> +#include "qemu/option.h"
>>> +#include "qemu/units.h"
>>> +#include "block/block_int.h"
>>> +
>>> +
>>> +typedef struct BDRVPreallocateState {
>>> +    int64_t prealloc_size;
>>> +    int64_t prealloc_align;
>>> +
>>> +    /*
>>> + * Filter is started as not-active, so it doesn't do any
>>> preallocations nor
>>> + * requires BLK_PERM_RESIZE on its child. This is needed to
>>> create filter
>>> + * above another node-child and then do bdrv_replace_node to
>>> insert the
>>> + * filter.
>>
>> A bit weird, but seems fair.  It’s basically just a cache for whether
>> this node has a writer on it or not.
>>
>> Apart from the weirdness, I don’t understand the “another node-child”.
>> Say you have “format” -> “proto”, and then you want to insert
>> “prealloc”.  Wouldn’t you blockdev-add prealloc,file=proto and then
>> blockdev-replace format.file=prealloc?
> 
> Yes something like this. Actually, I'm about inserting the filter
> automatically from block layer code, but your reasoning is about same
> thing and is better.
> 
>> So what is that “other node-child”?
> 
> Hmm, just my misleading wording. At least '-' in wrong place. Just
> "other node child", or "child of another node"..

OK.

>>> + *
>>> + * Filter becomes active the first time it detects that its
>>> parents have
>>> + * BLK_PERM_RESIZE on it.
>>> + * Filter becomes active forever: it doesn't lose active status
>>> if parents
>>> + * lose BLK_PERM_RESIZE, otherwise we'll not be able to shrink
>>> the file on
>>> + * filter close.
>>
>> Oh, the file is shrunk?  That wasn’t clear from the documentation.
>>
>> Hm.  Seems like useful behavior.  I just wonder if keeping the
>> permission around indefinitely makes sense.  Why not just truncate it
>> when the permission is revoked?
> 
> How? Parent is closed earlier, so on close we will not have the
> permission. So, we force-keep the permission up to our close().

I thought that preallocate_child_perm() would be invoked when the parent
is detached, so we could do the truncate there, before relinquishing
preallocate’s RESIZE permission.

[...]

>>> +static void preallocate_close(BlockDriverState *bs)
>>> +{
>>> +    BDRVPreallocateState *s = bs->opaque;
>>> +
>>> +    if (s->active && s->data_end >= 0 &&
>>> +    bdrv_getlength(bs->file->bs) > s->data_end)
>>> +    {
>>> +    bdrv_truncate(bs->file, s->data_end, true,
>>> PREALLOC_MODE_OFF, 0, NULL);
>>
>> Now that I think more about it...  What if there are other writers on
>> bs->file?  This may throw data away.
> 
> Good point. Actually, if bs->file has other writing parents, the logic
> of the filter
> around "data_end" is broken. So we must unshare WRITE and RESIZE
> permissions.

That’s certainly a heavy hammer, but it’d work.

>>  Maybe BDS.wr_highest_offset can
>> help to make a 

Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-26 Thread Vladimir Sementsov-Ogievskiy

24.08.2020 20:52, Vladimir Sementsov-Ogievskiy wrote:

21.08.2020 17:11, Vladimir Sementsov-Ogievskiy wrote:

It's intended to be inserted between format and protocol nodes to
preallocate additional space (expanding protocol file) on writes
crossing EOF. It improves performance for file-systems with slow
allocation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  docs/system/qemu-block-drivers.rst.inc |  26 +++
  qapi/block-core.json   |  20 +-
  block/preallocate.c    | 291 +
  block/Makefile.objs    |   1 +
  4 files changed, 337 insertions(+), 1 deletion(-)
  create mode 100644 block/preallocate.c

diff --git a/docs/system/qemu-block-drivers.rst.inc 
b/docs/system/qemu-block-drivers.rst.inc
index b052a6d14e..5e8a35c571 100644
--- a/docs/system/qemu-block-drivers.rst.inc
+++ b/docs/system/qemu-block-drivers.rst.inc
@@ -952,3 +952,29 @@ on host and see if there are locks held by the QEMU 
process on the image file.
  More than one byte could be locked by the QEMU instance, each byte of which
  reflects a particular permission that is acquired or protected by the running
  block driver.
+


[..]


+
+static coroutine_fn int preallocate_co_preadv_part(
+    BlockDriverState *bs, uint64_t offset, uint64_t bytes,
+    QEMUIOVector *qiov, size_t qiov_offset, int flags)
+{
+    return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
+   flags);
+}
+
+static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs,
+   int64_t offset, int bytes)
+{
+    return bdrv_co_pdiscard(bs->file, offset, bytes);
+}
+
+static bool coroutine_fn do_preallocate(BlockDriverState *bs, int64_t offset,
+   int64_t bytes, bool write_zero)
+{
+    BDRVPreallocateState *s = bs->opaque;
+    int64_t len, start, end;


int64_t old_data_end = s->data_end;


+
+    if (!s->active) {
+    return false;
+    }
+
+    if (s->data_end >= 0) {
+    s->data_end = MAX(s->data_end,
+  QEMU_ALIGN_UP(offset + bytes, BDRV_SECTOR_SIZE));
+    }
+
+    len = bdrv_getlength(bs->file->bs);
+    if (len < 0) {
+    return false;


return old_data_end >= 0 && offset >= old_data_end;


And with this small improvement we make the following test 20% faster (ssd, 
ext4):

./qemu-img create -f qcow2 $img 16G; ./qemu-img bench -c 15 -d 64 -f qcow2  
-s 16k -t none -n -w $img;

(assume additional patch which inserts the filter).

Great! So, preallocation is generally good idea, not only for vstorage.

What about inserting the filter by default?

I'll come tomorrow with more complete test results.



Some results:

the two commands to compare:
img=/ssd/x.qcow2; for i in {1..5}; do ./qemu-img create -f qcow2 $img 16G; 
./qemu-img bench -c 15 -d 64 -s 16k -t none -n -w --image-opts 
driver=qcow2,file.filename=$img; done
img=/ssd/x.qcow2; for i in {1..5}; do ./qemu-img create -f qcow2 $img 16G; 
./qemu-img bench -c 15 -d 64 -s 16k -t none -n -w --image-opts 
driver=qcow2,file.driver=preallocate,file.file.filename=$img; done


  no-filter  with-filter
ssd
  ext4: 6.94s  5.53s (-20%)
  xfs:  6.9s   25s (+262%)
hdd (with -c 45000)
  ext4: 8.23s  12.75s (+55%)
  xfs:  7.79s  25.4s (+226%)

vstorage (some custom distributed fs), with -c 4000 over ext4 over ssd: 42.9s 
~> 0.27s, more than 150 times faster with filter!
same, with -c 2000 over ext4 over hdd: 22.8s ~> 0.53s, ~43 times faster.


So, we do have large improvement for the vstorage (some custom distributed fs), 
which is our main target. And there is a significant improvement for ext4 over 
ssd. And (a lot more) significant degradation in other cases. For sure, we 
can't insert the filter by default, but it is useful.


--
Best regards,
Vladimir



Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-26 Thread Vladimir Sementsov-Ogievskiy

25.08.2020 18:11, Max Reitz wrote:

On 21.08.20 16:11, Vladimir Sementsov-Ogievskiy wrote:

It's intended to be inserted between format and protocol nodes to
preallocate additional space (expanding protocol file) on writes
crossing EOF. It improves performance for file-systems with slow
allocation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  docs/system/qemu-block-drivers.rst.inc |  26 +++
  qapi/block-core.json   |  20 +-
  block/preallocate.c| 291 +
  block/Makefile.objs|   1 +
  4 files changed, 337 insertions(+), 1 deletion(-)
  create mode 100644 block/preallocate.c


Looks good to me in essence.  Besides minor details, I wonder most about
whether truncating the file on close can be safe, but more about that below.


diff --git a/docs/system/qemu-block-drivers.rst.inc 
b/docs/system/qemu-block-drivers.rst.inc
index b052a6d14e..5e8a35c571 100644
--- a/docs/system/qemu-block-drivers.rst.inc
+++ b/docs/system/qemu-block-drivers.rst.inc
@@ -952,3 +952,29 @@ on host and see if there are locks held by the QEMU 
process on the image file.
  More than one byte could be locked by the QEMU instance, each byte of which
  reflects a particular permission that is acquired or protected by the running
  block driver.
+
+Filter drivers
+~~
+
+QEMU supports several filter drivers, which don't store any data, but do some


s/do/perform/


+additional tasks, hooking io requests.
+
+.. program:: filter-drivers
+.. option:: preallocate
+
+  Preallocate filter driver is intended to be inserted between format


*The preallocate filter driver


+  and protocol nodes and does preallocation of some additional space


I’d simplify this as s/does preallocation of/preallocates/


+  (expanding the protocol file) on write. It may be used for


I’d complicate this as s/on write/when writing past the file’s end/, or
“when data is written to the file after its end”, or at least “on
post-EOF writes”.

Maybe also s/It may be used for/This can be useful for/?


+  file-systems with slow allocation.
+
+  Supported options:
+
+  .. program:: preallocate
+  .. option:: prealloc-align
+
+On preallocation, align file length to this number, default 1M.


*the file length

As for “number”...  Well, it is a number.  But “value” might fit better.
  Or “length (in bytes)”?


+
+  .. program:: preallocate
+  .. option:: prealloc-size
+
+How much to preallocate, default 128M.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 197bdc1c36..b40448063b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2805,7 +2805,7 @@
  'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps',
  'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi',
  'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
-'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
+'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
  { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
  'sheepdog',
  'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
@@ -3074,6 +3074,23 @@
'data': { 'aes': 'QCryptoBlockOptionsQCow',
  'luks': 'QCryptoBlockOptionsLUKS'} }
  
+##

+# @BlockdevOptionsPreallocate:
+#
+# Filter driver intended to be inserted between format and protocol node
+# and do preallocation in protocol node on write.
+#
+# @prealloc-align: on preallocation, align file length to this number,
+# default 1048576 (1M)


Speaking of alignment, this second line isn’t properly aligned.


+#
+# @prealloc-size: how much to preallocate, default 134217728 (128M)
+#
+# Since: 5.2
+##
+{ 'struct': 'BlockdevOptionsPreallocate',
+  'base': 'BlockdevOptionsGenericFormat',
+  'data': { '*prealloc-align': 'int', '*prealloc-size': 'int' } }
+
  ##
  # @BlockdevOptionsQcow2:
  #
@@ -3979,6 +3996,7 @@
'null-co':'BlockdevOptionsNull',
'nvme':   'BlockdevOptionsNVMe',
'parallels':  'BlockdevOptionsGenericFormat',
+  'preallocate':'BlockdevOptionsPreallocate',
'qcow2':  'BlockdevOptionsQcow2',
'qcow':   'BlockdevOptionsQcow',
'qed':'BlockdevOptionsGenericCOWFormat',
diff --git a/block/preallocate.c b/block/preallocate.c
new file mode 100644
index 00..bdf54dbd2f
--- /dev/null
+++ b/block/preallocate.c
@@ -0,0 +1,291 @@
+/*
+ * preallocate filter driver
+ *
+ * The driver performs preallocate operation: it is injected above
+ * some node, and before each write over EOF it does additional preallocating
+ * write-zeroes request.
+ *
+ * Copyright (c) 2020 Virtuozzo International GmbH.
+ *
+ * Author:
+ *  Sementsov-Ogievskiy Vladimir 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 

Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-25 Thread Max Reitz
On 21.08.20 16:11, Vladimir Sementsov-Ogievskiy wrote:
> It's intended to be inserted between format and protocol nodes to
> preallocate additional space (expanding protocol file) on writes
> crossing EOF. It improves performance for file-systems with slow
> allocation.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  docs/system/qemu-block-drivers.rst.inc |  26 +++
>  qapi/block-core.json   |  20 +-
>  block/preallocate.c| 291 +
>  block/Makefile.objs|   1 +
>  4 files changed, 337 insertions(+), 1 deletion(-)
>  create mode 100644 block/preallocate.c

Looks good to me in essence.  Besides minor details, I wonder most about
whether truncating the file on close can be safe, but more about that below.

> diff --git a/docs/system/qemu-block-drivers.rst.inc 
> b/docs/system/qemu-block-drivers.rst.inc
> index b052a6d14e..5e8a35c571 100644
> --- a/docs/system/qemu-block-drivers.rst.inc
> +++ b/docs/system/qemu-block-drivers.rst.inc
> @@ -952,3 +952,29 @@ on host and see if there are locks held by the QEMU 
> process on the image file.
>  More than one byte could be locked by the QEMU instance, each byte of which
>  reflects a particular permission that is acquired or protected by the running
>  block driver.
> +
> +Filter drivers
> +~~
> +
> +QEMU supports several filter drivers, which don't store any data, but do some

s/do/perform/

> +additional tasks, hooking io requests.
> +
> +.. program:: filter-drivers
> +.. option:: preallocate
> +
> +  Preallocate filter driver is intended to be inserted between format

*The preallocate filter driver

> +  and protocol nodes and does preallocation of some additional space

I’d simplify this as s/does preallocation of/preallocates/

> +  (expanding the protocol file) on write. It may be used for

I’d complicate this as s/on write/when writing past the file’s end/, or
“when data is written to the file after its end”, or at least “on
post-EOF writes”.

Maybe also s/It may be used for/This can be useful for/?

> +  file-systems with slow allocation.
> +
> +  Supported options:
> +
> +  .. program:: preallocate
> +  .. option:: prealloc-align
> +
> +On preallocation, align file length to this number, default 1M.

*the file length

As for “number”...  Well, it is a number.  But “value” might fit better.
 Or “length (in bytes)”?

> +
> +  .. program:: preallocate
> +  .. option:: prealloc-size
> +
> +How much to preallocate, default 128M.
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 197bdc1c36..b40448063b 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -2805,7 +2805,7 @@
>  'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 
> 'ftps',
>  'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi',
>  'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
> -'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
> +'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
>  { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
>  'sheepdog',
>  'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
> @@ -3074,6 +3074,23 @@
>'data': { 'aes': 'QCryptoBlockOptionsQCow',
>  'luks': 'QCryptoBlockOptionsLUKS'} }
>  
> +##
> +# @BlockdevOptionsPreallocate:
> +#
> +# Filter driver intended to be inserted between format and protocol node
> +# and do preallocation in protocol node on write.
> +#
> +# @prealloc-align: on preallocation, align file length to this number,
> +# default 1048576 (1M)

Speaking of alignment, this second line isn’t properly aligned.

> +#
> +# @prealloc-size: how much to preallocate, default 134217728 (128M)
> +#
> +# Since: 5.2
> +##
> +{ 'struct': 'BlockdevOptionsPreallocate',
> +  'base': 'BlockdevOptionsGenericFormat',
> +  'data': { '*prealloc-align': 'int', '*prealloc-size': 'int' } }
> +
>  ##
>  # @BlockdevOptionsQcow2:
>  #
> @@ -3979,6 +3996,7 @@
>'null-co':'BlockdevOptionsNull',
>'nvme':   'BlockdevOptionsNVMe',
>'parallels':  'BlockdevOptionsGenericFormat',
> +  'preallocate':'BlockdevOptionsPreallocate',
>'qcow2':  'BlockdevOptionsQcow2',
>'qcow':   'BlockdevOptionsQcow',
>'qed':'BlockdevOptionsGenericCOWFormat',
> diff --git a/block/preallocate.c b/block/preallocate.c
> new file mode 100644
> index 00..bdf54dbd2f
> --- /dev/null
> +++ b/block/preallocate.c
> @@ -0,0 +1,291 @@
> +/*
> + * preallocate filter driver
> + *
> + * The driver performs preallocate operation: it is injected above
> + * some node, and before each write over EOF it does additional preallocating
> + * write-zeroes request.
> + *
> + * Copyright (c) 2020 Virtuozzo International GmbH.
> + *
> + * Author:
> + *  Sementsov-Ogievskiy Vladimir 
> + *
> + * This program is free 

Re: [PATCH v5 07/10] block: introduce preallocate filter

2020-08-24 Thread Vladimir Sementsov-Ogievskiy

21.08.2020 17:11, Vladimir Sementsov-Ogievskiy wrote:

It's intended to be inserted between format and protocol nodes to
preallocate additional space (expanding protocol file) on writes
crossing EOF. It improves performance for file-systems with slow
allocation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  docs/system/qemu-block-drivers.rst.inc |  26 +++
  qapi/block-core.json   |  20 +-
  block/preallocate.c| 291 +
  block/Makefile.objs|   1 +
  4 files changed, 337 insertions(+), 1 deletion(-)
  create mode 100644 block/preallocate.c

diff --git a/docs/system/qemu-block-drivers.rst.inc 
b/docs/system/qemu-block-drivers.rst.inc
index b052a6d14e..5e8a35c571 100644
--- a/docs/system/qemu-block-drivers.rst.inc
+++ b/docs/system/qemu-block-drivers.rst.inc
@@ -952,3 +952,29 @@ on host and see if there are locks held by the QEMU 
process on the image file.
  More than one byte could be locked by the QEMU instance, each byte of which
  reflects a particular permission that is acquired or protected by the running
  block driver.
+


[..]


+
+static coroutine_fn int preallocate_co_preadv_part(
+BlockDriverState *bs, uint64_t offset, uint64_t bytes,
+QEMUIOVector *qiov, size_t qiov_offset, int flags)
+{
+return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
+   flags);
+}
+
+static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs,
+   int64_t offset, int bytes)
+{
+return bdrv_co_pdiscard(bs->file, offset, bytes);
+}
+
+static bool coroutine_fn do_preallocate(BlockDriverState *bs, int64_t offset,
+   int64_t bytes, bool write_zero)
+{
+BDRVPreallocateState *s = bs->opaque;
+int64_t len, start, end;


int64_t old_data_end = s->data_end;


+
+if (!s->active) {
+return false;
+}
+
+if (s->data_end >= 0) {
+s->data_end = MAX(s->data_end,
+  QEMU_ALIGN_UP(offset + bytes, BDRV_SECTOR_SIZE));
+}
+
+len = bdrv_getlength(bs->file->bs);
+if (len < 0) {
+return false;


return old_data_end >= 0 && offset >= old_data_end;


And with this small improvement we make the following test 20% faster (ssd, 
ext4):

./qemu-img create -f qcow2 $img 16G; ./qemu-img bench -c 15 -d 64 -f qcow2  
-s 16k -t none -n -w $img;

(assume additional patch which inserts the filter).

Great! So, preallocation is generally good idea, not only for vstorage.

What about inserting the filter by default?

I'll come tomorrow with more complete test results.



--
Best regards,
Vladimir



[PATCH v5 07/10] block: introduce preallocate filter

2020-08-21 Thread Vladimir Sementsov-Ogievskiy
It's intended to be inserted between format and protocol nodes to
preallocate additional space (expanding protocol file) on writes
crossing EOF. It improves performance for file-systems with slow
allocation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 docs/system/qemu-block-drivers.rst.inc |  26 +++
 qapi/block-core.json   |  20 +-
 block/preallocate.c| 291 +
 block/Makefile.objs|   1 +
 4 files changed, 337 insertions(+), 1 deletion(-)
 create mode 100644 block/preallocate.c

diff --git a/docs/system/qemu-block-drivers.rst.inc 
b/docs/system/qemu-block-drivers.rst.inc
index b052a6d14e..5e8a35c571 100644
--- a/docs/system/qemu-block-drivers.rst.inc
+++ b/docs/system/qemu-block-drivers.rst.inc
@@ -952,3 +952,29 @@ on host and see if there are locks held by the QEMU 
process on the image file.
 More than one byte could be locked by the QEMU instance, each byte of which
 reflects a particular permission that is acquired or protected by the running
 block driver.
+
+Filter drivers
+~~
+
+QEMU supports several filter drivers, which don't store any data, but do some
+additional tasks, hooking io requests.
+
+.. program:: filter-drivers
+.. option:: preallocate
+
+  Preallocate filter driver is intended to be inserted between format
+  and protocol nodes and does preallocation of some additional space
+  (expanding the protocol file) on write. It may be used for
+  file-systems with slow allocation.
+
+  Supported options:
+
+  .. program:: preallocate
+  .. option:: prealloc-align
+
+On preallocation, align file length to this number, default 1M.
+
+  .. program:: preallocate
+  .. option:: prealloc-size
+
+How much to preallocate, default 128M.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 197bdc1c36..b40448063b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2805,7 +2805,7 @@
 'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps',
 'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi',
 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
-'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
+'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
 { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
 'sheepdog',
 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
@@ -3074,6 +3074,23 @@
   'data': { 'aes': 'QCryptoBlockOptionsQCow',
 'luks': 'QCryptoBlockOptionsLUKS'} }
 
+##
+# @BlockdevOptionsPreallocate:
+#
+# Filter driver intended to be inserted between format and protocol node
+# and do preallocation in protocol node on write.
+#
+# @prealloc-align: on preallocation, align file length to this number,
+# default 1048576 (1M)
+#
+# @prealloc-size: how much to preallocate, default 134217728 (128M)
+#
+# Since: 5.2
+##
+{ 'struct': 'BlockdevOptionsPreallocate',
+  'base': 'BlockdevOptionsGenericFormat',
+  'data': { '*prealloc-align': 'int', '*prealloc-size': 'int' } }
+
 ##
 # @BlockdevOptionsQcow2:
 #
@@ -3979,6 +3996,7 @@
   'null-co':'BlockdevOptionsNull',
   'nvme':   'BlockdevOptionsNVMe',
   'parallels':  'BlockdevOptionsGenericFormat',
+  'preallocate':'BlockdevOptionsPreallocate',
   'qcow2':  'BlockdevOptionsQcow2',
   'qcow':   'BlockdevOptionsQcow',
   'qed':'BlockdevOptionsGenericCOWFormat',
diff --git a/block/preallocate.c b/block/preallocate.c
new file mode 100644
index 00..bdf54dbd2f
--- /dev/null
+++ b/block/preallocate.c
@@ -0,0 +1,291 @@
+/*
+ * preallocate filter driver
+ *
+ * The driver performs preallocate operation: it is injected above
+ * some node, and before each write over EOF it does additional preallocating
+ * write-zeroes request.
+ *
+ * Copyright (c) 2020 Virtuozzo International GmbH.
+ *
+ * Author:
+ *  Sementsov-Ogievskiy Vladimir 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qemu/units.h"
+#include "block/block_int.h"
+
+
+typedef struct BDRVPreallocateState {
+int64_t prealloc_size;
+int64_t prealloc_align;
+
+/*
+ * Filter is started as not-active, so