diff mbox series

[v9,1/2] docs: improve qcow2 spec about extending image header

Message ID 20191216121733.63562-2-vsementsov@virtuozzo.com
State New
Headers show
Series qcow2: add zstd cluster compression | expand

Commit Message

Vladimir Sementsov-Ogievskiy Dec. 16, 2019, 12:17 p.m. UTC
Make it more obvious how to add new fields to the version 3 header and
how to interpret them.

The specification is adjusted so for new defined optional fields:

1. Software may support some of these optional fields and ignore the
   others, which means that features may be backported to downstream
   Qemu independently.
2. If we want to add incompatible field (or a field, for which some its
   values would be incompatible), it must be accompanied by
   incompatible feature bit.

Also the concept of "default is zero" is clarified, as it's strange to
say that the value of the field is assumed to be zero for the software
version which don't know about the field at all and don't know how to
treat it be it zero or not.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 docs/interop/qcow2.txt | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

Comments

Max Reitz Jan. 20, 2020, 4:03 p.m. UTC | #1
On 16.12.19 13:17, Vladimir Sementsov-Ogievskiy wrote:
> Make it more obvious how to add new fields to the version 3 header and
> how to interpret them.
> 
> The specification is adjusted so for new defined optional fields:
> 
> 1. Software may support some of these optional fields and ignore the
>    others, which means that features may be backported to downstream
>    Qemu independently.
> 2. If we want to add incompatible field (or a field, for which some its
>    values would be incompatible), it must be accompanied by
>    incompatible feature bit.
> 
> Also the concept of "default is zero" is clarified, as it's strange to
> say that the value of the field is assumed to be zero for the software
> version which don't know about the field at all and don't know how to
> treat it be it zero or not.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> ---
>  docs/interop/qcow2.txt | 39 ++++++++++++++++++++++++++++++++++++---
>  1 file changed, 36 insertions(+), 3 deletions(-)

I put review of this off for so long because I always waited for Eric to
give his R-b, but maybe not.

I generally think that he’s stricter on what to write in documentation,
and accordingly I only have nit picks on spelling and structure:

> diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
> index af5711e533..d92c827763 100644
> --- a/docs/interop/qcow2.txt
> +++ b/docs/interop/qcow2.txt
> @@ -79,9 +79,9 @@ The first cluster of a qcow2 image contains the file header:
>                      Offset into the image file at which the snapshot table
>                      starts. Must be aligned to a cluster boundary.
>  
> -If the version is 3 or higher, the header has the following additional fields.
> -For version 2, the values are assumed to be zero, unless specified otherwise
> -in the description of a field.
> +For version 2, the header is exactly 72 bytes in length, and finishes here.
> +For version 3 or higher, the header length is at least 104 bytes, including
> +the next fields through header_length.
>  
>           72 -  79:  incompatible_features
>                      Bitmask of incompatible features. An implementation must
> @@ -164,6 +164,39 @@ in the description of a field.
>          100 - 103:  header_length
>                      Length of the header structure in bytes. For version 2
>                      images, the length is always assumed to be 72 bytes.
> +                    For version 3 it's at least 104 bytes and must be a multiply

s/multiply/multiple/

> +                    of 8.
> +
> +Additional fields (version 3 and higher)

If this is supposed to be a heading, maybe it should enclosed by “===”
on both sides.

> +
> +In general, these fields are optional and may be safely ignored by the software,
> +as well as filled by zeros (which is equal to field absence), if software needs
> +to set field B, but don't want to care about field A, which precedes B. More

s/don't/does not/ (or maybe s/don't want/does not/)

> +formally, additional fields have the following compatibility rules:
> +
> +1. If the value of the additional field must not be ignored for correct
> +handling of the file, it will be accompanied by a corresponding incompatible
> +feature bit.
> +
> +2. If there are no unrecognized incompatible feature bits set, an unknown
> +additional field may be safely ignored other than preserving its value when
> +rewriting the image header.
> +
> +3. An explicit value of 0 will have the same behavior as when the field is not
> +present*, if not altered by specific incompatible bit.

s/by specific/by a specific/

> +
> +*. Field is not present when header_length is less or equal to field's offset.

s/Field/A field/, s/field's/the field's/

(maybe also +considered, as in "A field is considered not present...")

> +Also, all additional fields are not present for version 2.
> +
> +        < ... No additional fields in the header currently ... >

This looks a bit weird to me, but the next patch will remove it again,
so who cares.

> +Header padding

Same heading note here (I’d make this “=== Header padding ===”).

> +
> +@header_length must be a multiply of 8, which means that if last additional field

s/multiply/multiple/

> +end is not aligned, some padding is needed. This padding must be zeroed, so that,

I think s/last additional field end/the last additional field’s end/, or
maybe s/last additional field end/the end of the last additional field/.

> +if some existing (or future) additional field will fall into the padding, it
> +will be interpreted accordingly to point [3.] of the previous paragraph, i.e.
> +in same manner as when this field is not present.

s/in same/in the same/

>  

I think there should be a new heading here
(“=== Header extensions ===”).

Max

>  Directly after the image header, optional sections called header extensions can
>  be stored. Each extension has a structure like the following:
>
Vladimir Sementsov-Ogievskiy Jan. 20, 2020, 4:40 p.m. UTC | #2
20.01.2020 19:03, Max Reitz wrote:
> On 16.12.19 13:17, Vladimir Sementsov-Ogievskiy wrote:
>> Make it more obvious how to add new fields to the version 3 header and
>> how to interpret them.
>>
>> The specification is adjusted so for new defined optional fields:
>>
>> 1. Software may support some of these optional fields and ignore the
>>     others, which means that features may be backported to downstream
>>     Qemu independently.
>> 2. If we want to add incompatible field (or a field, for which some its
>>     values would be incompatible), it must be accompanied by
>>     incompatible feature bit.
>>
>> Also the concept of "default is zero" is clarified, as it's strange to
>> say that the value of the field is assumed to be zero for the software
>> version which don't know about the field at all and don't know how to
>> treat it be it zero or not.
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>> ---
>>   docs/interop/qcow2.txt | 39 ++++++++++++++++++++++++++++++++++++---
>>   1 file changed, 36 insertions(+), 3 deletions(-)
> 
> I put review of this off for so long because I always waited for Eric to
> give his R-b, but maybe not.
> 
> I generally think that he’s stricter on what to write in documentation,
> and accordingly I only have nit picks on spelling and structure:

This is very helpful too, thanks.

I'll resend now with your suggestions, to make it easier to read for others.

> 
>> diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
>> index af5711e533..d92c827763 100644
>> --- a/docs/interop/qcow2.txt
>> +++ b/docs/interop/qcow2.txt
>> @@ -79,9 +79,9 @@ The first cluster of a qcow2 image contains the file header:
>>                       Offset into the image file at which the snapshot table
>>                       starts. Must be aligned to a cluster boundary.
>>   
>> -If the version is 3 or higher, the header has the following additional fields.
>> -For version 2, the values are assumed to be zero, unless specified otherwise
>> -in the description of a field.
>> +For version 2, the header is exactly 72 bytes in length, and finishes here.
>> +For version 3 or higher, the header length is at least 104 bytes, including
>> +the next fields through header_length.
>>   
>>            72 -  79:  incompatible_features
>>                       Bitmask of incompatible features. An implementation must
>> @@ -164,6 +164,39 @@ in the description of a field.
>>           100 - 103:  header_length
>>                       Length of the header structure in bytes. For version 2
>>                       images, the length is always assumed to be 72 bytes.
>> +                    For version 3 it's at least 104 bytes and must be a multiply
> 
> s/multiply/multiple/
> 
>> +                    of 8.
>> +
>> +Additional fields (version 3 and higher)
> 
> If this is supposed to be a heading, maybe it should enclosed by “===”
> on both sides.
> 
>> +
>> +In general, these fields are optional and may be safely ignored by the software,
>> +as well as filled by zeros (which is equal to field absence), if software needs
>> +to set field B, but don't want to care about field A, which precedes B. More
> 
> s/don't/does not/ (or maybe s/don't want/does not/)
> 
>> +formally, additional fields have the following compatibility rules:
>> +
>> +1. If the value of the additional field must not be ignored for correct
>> +handling of the file, it will be accompanied by a corresponding incompatible
>> +feature bit.
>> +
>> +2. If there are no unrecognized incompatible feature bits set, an unknown
>> +additional field may be safely ignored other than preserving its value when
>> +rewriting the image header.
>> +
>> +3. An explicit value of 0 will have the same behavior as when the field is not
>> +present*, if not altered by specific incompatible bit.
> 
> s/by specific/by a specific/
> 
>> +
>> +*. Field is not present when header_length is less or equal to field's offset.
> 
> s/Field/A field/, s/field's/the field's/
> 
> (maybe also +considered, as in "A field is considered not present...")
> 
>> +Also, all additional fields are not present for version 2.
>> +
>> +        < ... No additional fields in the header currently ... >
> 
> This looks a bit weird to me, but the next patch will remove it again,
> so who cares.
> 
>> +Header padding
> 
> Same heading note here (I’d make this “=== Header padding ===”).
> 
>> +
>> +@header_length must be a multiply of 8, which means that if last additional field
> 
> s/multiply/multiple/
> 
>> +end is not aligned, some padding is needed. This padding must be zeroed, so that,
> 
> I think s/last additional field end/the last additional field’s end/, or
> maybe s/last additional field end/the end of the last additional field/.
> 
>> +if some existing (or future) additional field will fall into the padding, it
>> +will be interpreted accordingly to point [3.] of the previous paragraph, i.e.
>> +in same manner as when this field is not present.
> 
> s/in same/in the same/
> 
>>   
> 
> I think there should be a new heading here
> (“=== Header extensions ===”).
> 
> Max
> 
>>   Directly after the image header, optional sections called header extensions can
>>   be stored. Each extension has a structure like the following:
>>
>
diff mbox series

Patch

diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
index af5711e533..d92c827763 100644
--- a/docs/interop/qcow2.txt
+++ b/docs/interop/qcow2.txt
@@ -79,9 +79,9 @@  The first cluster of a qcow2 image contains the file header:
                     Offset into the image file at which the snapshot table
                     starts. Must be aligned to a cluster boundary.
 
-If the version is 3 or higher, the header has the following additional fields.
-For version 2, the values are assumed to be zero, unless specified otherwise
-in the description of a field.
+For version 2, the header is exactly 72 bytes in length, and finishes here.
+For version 3 or higher, the header length is at least 104 bytes, including
+the next fields through header_length.
 
          72 -  79:  incompatible_features
                     Bitmask of incompatible features. An implementation must
@@ -164,6 +164,39 @@  in the description of a field.
         100 - 103:  header_length
                     Length of the header structure in bytes. For version 2
                     images, the length is always assumed to be 72 bytes.
+                    For version 3 it's at least 104 bytes and must be a multiply
+                    of 8.
+
+Additional fields (version 3 and higher)
+
+In general, these fields are optional and may be safely ignored by the software,
+as well as filled by zeros (which is equal to field absence), if software needs
+to set field B, but don't want to care about field A, which precedes B. More
+formally, additional fields have the following compatibility rules:
+
+1. If the value of the additional field must not be ignored for correct
+handling of the file, it will be accompanied by a corresponding incompatible
+feature bit.
+
+2. If there are no unrecognized incompatible feature bits set, an unknown
+additional field may be safely ignored other than preserving its value when
+rewriting the image header.
+
+3. An explicit value of 0 will have the same behavior as when the field is not
+present*, if not altered by specific incompatible bit.
+
+*. Field is not present when header_length is less or equal to field's offset.
+Also, all additional fields are not present for version 2.
+
+        < ... No additional fields in the header currently ... >
+
+Header padding
+
+@header_length must be a multiply of 8, which means that if last additional field
+end is not aligned, some padding is needed. This padding must be zeroed, so that,
+if some existing (or future) additional field will fall into the padding, it
+will be interpreted accordingly to point [3.] of the previous paragraph, i.e.
+in same manner as when this field is not present.
 
 Directly after the image header, optional sections called header extensions can
 be stored. Each extension has a structure like the following: