[PATCH v2 5/5] vvfat: add support for "fat-size" options

Clément Chigot posted 5 patches 1 week ago
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>
[PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Clément Chigot 1 week ago
This allows more flexibility to vvfat backend. The values of "Number of
Heads" and "Sectors per track" are based on SD specifications Part 2.

Due to the FAT architecture, not all sizes are reachable. Therefore, it
could be round up to the closest available size.

FAT32 has not been adjusted and thus still default to 504 Mib.

For floppy, only 1440 Kib and 2880 Kib are supported.

Signed-off-by: Clément Chigot <chigot@adacore.com>
---
 block/vvfat.c        | 169 ++++++++++++++++++++++++++++++++++++++-----
 qapi/block-core.json |   8 +-
 2 files changed, 158 insertions(+), 19 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index b0e591e35e..96f5062939 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1095,6 +1095,11 @@ static QemuOptsList runtime_opts = {
             .def_value_str = "true",
             .help = "Do not add a Master Boot Record on this disk",
         },
+        {
+            .name = "fat-size",
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
         { /* end of list */ }
     },
 };
@@ -1152,10 +1157,150 @@ static void vvfat_parse_filename(const char *filename, QDict *options,
     qdict_put_bool(options, "partitioned", partitioned);
 }
 
+static void vvfat_get_size_parameters(uint64_t size, BDRVVVFATState *s,
+                                      bool floppy, Error **errp)
+{
+    if (floppy) {
+        if (s->fat_type == 16) {
+            /* The default for floppy FAT 16 is 2880 KiB */
+            if (!size) {
+                size = 2880 * 1024;
+            }
+
+            if (size != 2880 * 1024) {
+                error_setg(errp,
+                           "floppy FAT16 unsupported size; only support "
+                           "2880 KiB");
+            }
+
+        } else {
+            /* The default for floppy FAT 12 is 1440 KiB */
+            if (!size) {
+                size = 1440 * 1024;
+            }
+
+            if (size != 2880 * 1024 && size != 1440 * 1024) {
+                error_setg(errp,
+                           "floppy FAT12 unsupported size; only support "
+                           "1440 KiB or 2880 KiB");
+            }
+
+        }
+
+        if (s->fat_type == 12) {
+            if (size == 2880 * 1024) {
+                s->sectors_per_track = 36;
+            } else {
+                s->sectors_per_track = 18;
+            }
+        } else {
+            s->sectors_per_track = 36;
+        }
+
+        s->sectors_per_cluster = 0x10;
+        s->cylinders = 80;
+        s->number_of_heads = 2;
+    } else {
+
+        switch (s->fat_type) {
+        case 32:
+            /* TODO FAT32 adjust  */
+            if (size) {
+                warn_report("size parameters not supported with FAT32;"
+                            "default to 504 MiB.");
+            }
+            s->cylinders = 1024;
+            s->number_of_heads = 16;
+            s->sectors_per_cluster = 0x10;
+            s->sectors_per_track = 63;
+            return;
+
+        case 12:
+
+            /* Default is 32 MB */
+            if (!size) {
+                size = 32 * 1024 * 1024;
+            } else if (size > 32 * 1024 * 1024) {
+                error_setg(errp, "FAT12 unsupported size; higher than 32 MiB");
+            }
+
+            s->sectors_per_cluster = 0x10;
+            s->cylinders = 64;
+
+            /*
+             * Based on CHS Recommandation table:
+             *  Card Capacity | Number of Headers | Sectors per track
+             *      2 MiB     |         4         |       16
+             *      4 MiB     |         8         |       16
+             *      8 MiB     |        16         |       16
+             *      16 MiB    |         2         |       32
+             *      32 MiB    |         4         |       32
+             *
+             * For 2 MiB, the recommendation is heads = 2 and sectors = 16, but
+             * this requires a different number of cylinders. Thus, it was
+             * adjusted to keep this number constant.
+             */
+            if (size <= 8 * 1024 * 1024) {
+                s->sectors_per_track = 16;
+            } else {
+                s->sectors_per_track = 32;
+            }
+
+            break;
+
+        case 16:
+            /* Default is 504 MiB */
+            if (!size) {
+                size = 504 * 1024 * 1024;
+            } else if (size / 1024 > 4 * 1024 * 1024) {
+                error_setg(errp, "FAT16 unsupported size; higher than 4 GiB");
+            }
+
+            s->sectors_per_cluster = 0x10;
+            s->cylinders = 1024;
+
+            /*
+             * Based on CHS Recommandation table:
+             *  Card Capacity | Number of Headers | Sectors per track
+             *      64 MiB    |         4         |       32
+             *     128 MiB    |         8         |       32
+             *     256 MiB    |        16         |       32
+             *     504 MiB    |        16         |       63
+             *    1008 MiB    |        32         |       63
+             *    2016 MiB    |        64         |       63
+             */
+            if (size <= 256 * 1024 * 1024) {
+                s->sectors_per_track = 32;
+            } else {
+                s->sectors_per_track = 63;
+            }
+
+            break;
+        }
+
+        /*
+         * The formula between the size (in bytes) and the parameters are:
+         *  size = VVFAT_SECTOR_SIZE * sectors_per_track * number_of_headers *
+         *         cylinders
+         *
+         */
+        s->number_of_heads = size / s->sectors_per_track /
+            VVFAT_SECTOR_SIZE / s->cylinders;
+
+        /* Round up to the closest size if the given one cannot be reached. */
+        if (size %
+            (s->sectors_per_track * VVFAT_SECTOR_SIZE * s->cylinders) != 0) {
+            s->number_of_heads++;
+        }
+
+    }
+}
+
 static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
                       Error **errp)
 {
     BDRVVVFATState *s = bs->opaque;
+    uint64_t size;
     bool floppy;
     const char *dirname, *label;
     QemuOpts *opts;
@@ -1182,6 +1327,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
 
     s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
     floppy = qemu_opt_get_bool(opts, "floppy", false);
+    size = qemu_opt_get_size_del(opts, "fat-size", 0);
 
     memset(s->volume_label, ' ', sizeof(s->volume_label));
     label = qemu_opt_get(opts, "label");
@@ -1219,29 +1365,15 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
+    vvfat_get_size_parameters(size, s, floppy, errp);
 
-    if (floppy) {
-        /* Choose floppy size. 1440 KiB for FAT 12, 2880 KiB for FAT-16 */
-        s->sectors_per_track = s->fat_type == 12 ? 18 : 36;
-        s->cylinders = 80;
-        s->number_of_heads = 2;
-    } else {
-        /* Reserver space for MBR */
-        if (qemu_opt_get_bool(opts, "partitioned", true)) {
-            s->offset_to_bootsector = 0x3f;
-        }
-        /* 32MB or 504MB disk*/
-        s->cylinders = s->fat_type == 12 ? 64 : 1024;
-        s->number_of_heads = 16;
-        s->sectors_per_track = 63;
+    /* Reserver space for MBR */
+    if (!floppy && qemu_opt_get_bool(opts, "partitioned", true)) {
+        s->offset_to_bootsector = 0x3f;
     }
 
-
     s->bs = bs;
 
-    /* LATER TODO: if FAT32, adjust */
-    s->sectors_per_cluster=0x10;
-
     s->current_cluster=0xffffffff;
 
     s->qcow = NULL;
@@ -3280,6 +3412,7 @@ static const char *const vvfat_strong_runtime_opts[] = {
     "label",
     "rw",
     "partitioned",
+    "fat-size",
 
     NULL
 };
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 8a479ba090..0bcb360320 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3478,11 +3478,17 @@
 #     (default: true)
 #     (since 10.2)
 #
+# @fat-size: size of the device in bytes.  Due to FAT underlying
+#     architecture, this size can be rounded up to the closest valid
+#     size.
+#     (since 10.2)
+#
 # Since: 2.9
 ##
 { 'struct': 'BlockdevOptionsVVFAT',
   'data': { 'dir': 'str', '*fat-type': 'int', '*floppy': 'bool',
-            '*label': 'str', '*rw': 'bool', '*partitioned': 'bool' } }
+            '*label': 'str', '*rw': 'bool', '*partitioned': 'bool',
+            'fat-size': 'int' } }
 
 ##
 # @BlockdevOptionsGenericFormat:
-- 
2.43.0


Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Markus Armbruster 4 days, 5 hours ago
Clément Chigot <chigot@adacore.com> writes:

> This allows more flexibility to vvfat backend. The values of "Number of
> Heads" and "Sectors per track" are based on SD specifications Part 2.
>
> Due to the FAT architecture, not all sizes are reachable. Therefore, it
> could be round up to the closest available size.
>
> FAT32 has not been adjusted and thus still default to 504 Mib.
>
> For floppy, only 1440 Kib and 2880 Kib are supported.
>
> Signed-off-by: Clément Chigot <chigot@adacore.com>

[...]

> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 8a479ba090..0bcb360320 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -3478,11 +3478,17 @@
>  #     (default: true)
>  #     (since 10.2)
>  #
> +# @fat-size: size of the device in bytes.  Due to FAT underlying
> +#     architecture, this size can be rounded up to the closest valid
> +#     size.
> +#     (since 10.2)
> +#

Can you explain again why you moved from @size to @fat-size?

I assume you dropped the horrible special floppy sizes because ordinary
sizes suffice.  Correct?

>  # Since: 2.9
>  ##
>  { 'struct': 'BlockdevOptionsVVFAT',
>    'data': { 'dir': 'str', '*fat-type': 'int', '*floppy': 'bool',
> -            '*label': 'str', '*rw': 'bool', '*partitioned': 'bool' } }
> +            '*label': 'str', '*rw': 'bool', '*partitioned': 'bool',
> +            'fat-size': 'int' } }
>  
>  ##
>  # @BlockdevOptionsGenericFormat:
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Clément Chigot 4 days, 2 hours ago
On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
>
> Clément Chigot <chigot@adacore.com> writes:
>
> > This allows more flexibility to vvfat backend. The values of "Number of
> > Heads" and "Sectors per track" are based on SD specifications Part 2.
> >
> > Due to the FAT architecture, not all sizes are reachable. Therefore, it
> > could be round up to the closest available size.
> >
> > FAT32 has not been adjusted and thus still default to 504 Mib.
> >
> > For floppy, only 1440 Kib and 2880 Kib are supported.
> >
> > Signed-off-by: Clément Chigot <chigot@adacore.com>
>
> [...]
>
> > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > index 8a479ba090..0bcb360320 100644
> > --- a/qapi/block-core.json
> > +++ b/qapi/block-core.json
> > @@ -3478,11 +3478,17 @@
> >  #     (default: true)
> >  #     (since 10.2)
> >  #
> > +# @fat-size: size of the device in bytes.  Due to FAT underlying
> > +#     architecture, this size can be rounded up to the closest valid
> > +#     size.
> > +#     (since 10.2)
> > +#
>
> Can you explain again why you moved from @size to @fat-size?

Just to be sure, you mean in the above comment, in the commit message or both ?

> I assume you dropped the horrible special floppy sizes because ordinary
> sizes suffice.  Correct?

Yes. Clearly better that way.

> >  # Since: 2.9
> >  ##
> >  { 'struct': 'BlockdevOptionsVVFAT',
> >    'data': { 'dir': 'str', '*fat-type': 'int', '*floppy': 'bool',
> > -            '*label': 'str', '*rw': 'bool', '*partitioned': 'bool' } }
> > +            '*label': 'str', '*rw': 'bool', '*partitioned': 'bool',
> > +            'fat-size': 'int' } }
> >
> >  ##
> >  # @BlockdevOptionsGenericFormat:
>
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Markus Armbruster 4 days, 2 hours ago
Clément Chigot <chigot@adacore.com> writes:

> On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
>>
>> Clément Chigot <chigot@adacore.com> writes:
>>
>> > This allows more flexibility to vvfat backend. The values of "Number of
>> > Heads" and "Sectors per track" are based on SD specifications Part 2.
>> >
>> > Due to the FAT architecture, not all sizes are reachable. Therefore, it
>> > could be round up to the closest available size.
>> >
>> > FAT32 has not been adjusted and thus still default to 504 Mib.
>> >
>> > For floppy, only 1440 Kib and 2880 Kib are supported.
>> >
>> > Signed-off-by: Clément Chigot <chigot@adacore.com>
>>
>> [...]
>>
>> > diff --git a/qapi/block-core.json b/qapi/block-core.json
>> > index 8a479ba090..0bcb360320 100644
>> > --- a/qapi/block-core.json
>> > +++ b/qapi/block-core.json
>> > @@ -3478,11 +3478,17 @@
>> >  #     (default: true)
>> >  #     (since 10.2)
>> >  #
>> > +# @fat-size: size of the device in bytes.  Due to FAT underlying
>> > +#     architecture, this size can be rounded up to the closest valid
>> > +#     size.
>> > +#     (since 10.2)
>> > +#
>>
>> Can you explain again why you moved from @size to @fat-size?
>
> Just to be sure, you mean in the above comment, in the commit message or both ?

Just to me, because I'm not sure I like the change, but that may well be
due to a lack of understanding of your reasons.

[...]
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Clément Chigot 4 days, 1 hour ago
On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
>
> Clément Chigot <chigot@adacore.com> writes:
>
> > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
> >>
> >> Clément Chigot <chigot@adacore.com> writes:
> >>
> >> > This allows more flexibility to vvfat backend. The values of "Number of
> >> > Heads" and "Sectors per track" are based on SD specifications Part 2.
> >> >
> >> > Due to the FAT architecture, not all sizes are reachable. Therefore, it
> >> > could be round up to the closest available size.
> >> >
> >> > FAT32 has not been adjusted and thus still default to 504 Mib.
> >> >
> >> > For floppy, only 1440 Kib and 2880 Kib are supported.
> >> >
> >> > Signed-off-by: Clément Chigot <chigot@adacore.com>
> >>
> >> [...]
> >>
> >> > diff --git a/qapi/block-core.json b/qapi/block-core.json
> >> > index 8a479ba090..0bcb360320 100644
> >> > --- a/qapi/block-core.json
> >> > +++ b/qapi/block-core.json
> >> > @@ -3478,11 +3478,17 @@
> >> >  #     (default: true)
> >> >  #     (since 10.2)
> >> >  #
> >> > +# @fat-size: size of the device in bytes.  Due to FAT underlying
> >> > +#     architecture, this size can be rounded up to the closest valid
> >> > +#     size.
> >> > +#     (since 10.2)
> >> > +#
> >>
> >> Can you explain again why you moved from @size to @fat-size?
> >
> > Just to be sure, you mean in the above comment, in the commit message or both ?
>
> Just to me, because I'm not sure I like the change, but that may well be
> due to a lack of understanding of your reasons.

Naming `fat-size` instead of `size` ensures the parameter is only
recognized by the vvfat backend. In particular, it will be refused by
the default raw format, avoiding confusion:
 "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
truncated to 256M, raw format being implicit.
 "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
unsupported by raw format.
 "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
 "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
unsupported by vvfat format.
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Markus Armbruster 4 days, 1 hour ago
Clément Chigot <chigot@adacore.com> writes:

> On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
>>
>> Clément Chigot <chigot@adacore.com> writes:
>>
>> > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
>> >>
>> >> Clément Chigot <chigot@adacore.com> writes:
>> >>
>> >> > This allows more flexibility to vvfat backend. The values of "Number of
>> >> > Heads" and "Sectors per track" are based on SD specifications Part 2.
>> >> >
>> >> > Due to the FAT architecture, not all sizes are reachable. Therefore, it
>> >> > could be round up to the closest available size.
>> >> >
>> >> > FAT32 has not been adjusted and thus still default to 504 Mib.
>> >> >
>> >> > For floppy, only 1440 Kib and 2880 Kib are supported.
>> >> >
>> >> > Signed-off-by: Clément Chigot <chigot@adacore.com>
>> >>
>> >> [...]
>> >>
>> >> > diff --git a/qapi/block-core.json b/qapi/block-core.json
>> >> > index 8a479ba090..0bcb360320 100644
>> >> > --- a/qapi/block-core.json
>> >> > +++ b/qapi/block-core.json
>> >> > @@ -3478,11 +3478,17 @@
>> >> >  #     (default: true)
>> >> >  #     (since 10.2)
>> >> >  #
>> >> > +# @fat-size: size of the device in bytes.  Due to FAT underlying
>> >> > +#     architecture, this size can be rounded up to the closest valid
>> >> > +#     size.
>> >> > +#     (since 10.2)
>> >> > +#
>> >>
>> >> Can you explain again why you moved from @size to @fat-size?
>> >
>> > Just to be sure, you mean in the above comment, in the commit message or both ?
>>
>> Just to me, because I'm not sure I like the change, but that may well be
>> due to a lack of understanding of your reasons.
>
> Naming `fat-size` instead of `size` ensures the parameter is only
> recognized by the vvfat backend. In particular, it will be refused by
> the default raw format, avoiding confusion:
>  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
> truncated to 256M, raw format being implicit.
>  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
> unsupported by raw format.

I figure throwing in format=raw to make raw format explicit doesn't
change anything.  Correct?

>  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
>  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
> unsupported by vvfat format.

If it was called @size, what behavior would we get?  Just two cases, I
think:

1. With raw format:

    -drive file=fat:<path>,size=256M

2. Without raw format:

    -drive file=fat:<path>,format=vvfat,size=256M
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Kevin Wolf 4 days ago
Am 10.11.2025 um 14:42 hat Markus Armbruster geschrieben:
> Clément Chigot <chigot@adacore.com> writes:
> 
> > On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
> >>
> >> Clément Chigot <chigot@adacore.com> writes:
> >>
> >> > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
> >> >>
> >> >> Clément Chigot <chigot@adacore.com> writes:
> >> >>
> >> >> > This allows more flexibility to vvfat backend. The values of "Number of
> >> >> > Heads" and "Sectors per track" are based on SD specifications Part 2.
> >> >> >
> >> >> > Due to the FAT architecture, not all sizes are reachable. Therefore, it
> >> >> > could be round up to the closest available size.
> >> >> >
> >> >> > FAT32 has not been adjusted and thus still default to 504 Mib.
> >> >> >
> >> >> > For floppy, only 1440 Kib and 2880 Kib are supported.
> >> >> >
> >> >> > Signed-off-by: Clément Chigot <chigot@adacore.com>
> >> >>
> >> >> [...]
> >> >>
> >> >> > diff --git a/qapi/block-core.json b/qapi/block-core.json
> >> >> > index 8a479ba090..0bcb360320 100644
> >> >> > --- a/qapi/block-core.json
> >> >> > +++ b/qapi/block-core.json
> >> >> > @@ -3478,11 +3478,17 @@
> >> >> >  #     (default: true)
> >> >> >  #     (since 10.2)
> >> >> >  #
> >> >> > +# @fat-size: size of the device in bytes.  Due to FAT underlying
> >> >> > +#     architecture, this size can be rounded up to the closest valid
> >> >> > +#     size.
> >> >> > +#     (since 10.2)
> >> >> > +#
> >> >>
> >> >> Can you explain again why you moved from @size to @fat-size?
> >> >
> >> > Just to be sure, you mean in the above comment, in the commit message or both ?
> >>
> >> Just to me, because I'm not sure I like the change, but that may well be
> >> due to a lack of understanding of your reasons.
> >
> > Naming `fat-size` instead of `size` ensures the parameter is only
> > recognized by the vvfat backend. In particular, it will be refused by
> > the default raw format, avoiding confusion:
> >  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
> > truncated to 256M, raw format being implicit.
> >  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
> > unsupported by raw format.
> 
> I figure throwing in format=raw to make raw format explicit doesn't
> change anything.  Correct?
> 
> >  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
> >  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
> > unsupported by vvfat format.
> 
> If it was called @size, what behavior would we get?  Just two cases, I
> think:
> 
> 1. With raw format:
> 
>     -drive file=fat:<path>,size=256M

You'd silently get a 504 MiB filesystem truncated to 256 MiB (i.e. a
corrupted file system). It's quite easy to forget format=vvfat, so
something that initially looks like it might be working is not a great
result for this user error.

> 2. Without raw format:
> 
>     -drive file=fat:<path>,format=vvfat,size=256M

This does the thing that you actually want, a 256 MiB file system.

I suggested to rename the vvfat option in v1 to make accidents at least
a bit less likely. I'm not completely sure if "fat-size" is the best
name, though, as it sounds as if it referred to the FAT itself instead
of the FAT filesystem. Maybe "fs-size"?

Kevin


Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Markus Armbruster 3 days, 7 hours ago
Kevin Wolf <kwolf@redhat.com> writes:

> Am 10.11.2025 um 14:42 hat Markus Armbruster geschrieben:
>> Clément Chigot <chigot@adacore.com> writes:
>> 
>> > On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
>> >>
>> >> Clément Chigot <chigot@adacore.com> writes:
>> >>
>> >> > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
>> >> >>
>> >> >> Clément Chigot <chigot@adacore.com> writes:
>> >> >>
>> >> >> > This allows more flexibility to vvfat backend. The values of "Number of
>> >> >> > Heads" and "Sectors per track" are based on SD specifications Part 2.
>> >> >> >
>> >> >> > Due to the FAT architecture, not all sizes are reachable. Therefore, it
>> >> >> > could be round up to the closest available size.
>> >> >> >
>> >> >> > FAT32 has not been adjusted and thus still default to 504 Mib.
>> >> >> >
>> >> >> > For floppy, only 1440 Kib and 2880 Kib are supported.
>> >> >> >
>> >> >> > Signed-off-by: Clément Chigot <chigot@adacore.com>
>> >> >>
>> >> >> [...]
>> >> >>
>> >> >> > diff --git a/qapi/block-core.json b/qapi/block-core.json
>> >> >> > index 8a479ba090..0bcb360320 100644
>> >> >> > --- a/qapi/block-core.json
>> >> >> > +++ b/qapi/block-core.json
>> >> >> > @@ -3478,11 +3478,17 @@
>> >> >> >  #     (default: true)
>> >> >> >  #     (since 10.2)
>> >> >> >  #
>> >> >> > +# @fat-size: size of the device in bytes.  Due to FAT underlying
>> >> >> > +#     architecture, this size can be rounded up to the closest valid
>> >> >> > +#     size.
>> >> >> > +#     (since 10.2)
>> >> >> > +#
>> >> >>
>> >> >> Can you explain again why you moved from @size to @fat-size?
>> >> >
>> >> > Just to be sure, you mean in the above comment, in the commit message or both ?
>> >>
>> >> Just to me, because I'm not sure I like the change, but that may well be
>> >> due to a lack of understanding of your reasons.
>> >
>> > Naming `fat-size` instead of `size` ensures the parameter is only
>> > recognized by the vvfat backend. In particular, it will be refused by
>> > the default raw format, avoiding confusion:
>> >  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
>> > truncated to 256M, raw format being implicit.
>> >  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
>> > unsupported by raw format.
>> 
>> I figure throwing in format=raw to make raw format explicit doesn't
>> change anything.  Correct?
>> 
>> >  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
>> >  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
>> > unsupported by vvfat format.
>> 
>> If it was called @size, what behavior would we get?  Just two cases, I
>> think:
>> 
>> 1. With raw format:
>> 
>>     -drive file=fat:<path>,size=256M
>
> You'd silently get a 504 MiB filesystem truncated to 256 MiB (i.e. a
> corrupted file system). It's quite easy to forget format=vvfat, so
> something that initially looks like it might be working is not a great
> result for this user error.
>
>> 2. Without raw format:
>> 
>>     -drive file=fat:<path>,format=vvfat,size=256M
>
> This does the thing that you actually want, a 256 MiB file system.
>
> I suggested to rename the vvfat option in v1 to make accidents at least
> a bit less likely.

Valid point.

The "raw" format's slicing feature has dangerous sharp edges.

I'm all for with giving users poweful tools, even if they're dangerous.
However, as we can see here, this one can interact badly with the
implicit use of "raw".  Adding the slicing feature to "raw" may have
been a mistake, and naming one of its configuration options "size"
definitely was a mistake.  Something like @slice-offset and @slize-size
would've been safer.

Anyway, the interface is set in stone now.

>                    I'm not completely sure if "fat-size" is the best
> name, though, as it sounds as if it referred to the FAT itself instead
> of the FAT filesystem. Maybe "fs-size"?

Better.  It's the size of the image, though, not the size of the
filesystem.  They are the same only if there's no MBR.
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by BALATON Zoltan 3 days, 23 hours ago
On Mon, 10 Nov 2025, Kevin Wolf wrote:
> Am 10.11.2025 um 14:42 hat Markus Armbruster geschrieben:
>> Clément Chigot <chigot@adacore.com> writes:
>>
>>> On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
>>>>
>>>> Clément Chigot <chigot@adacore.com> writes:
>>>>
>>>>> On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
>>>>>>
>>>>>> Clément Chigot <chigot@adacore.com> writes:
>>>>>>
>>>>>>> This allows more flexibility to vvfat backend. The values of "Number of
>>>>>>> Heads" and "Sectors per track" are based on SD specifications Part 2.
>>>>>>>
>>>>>>> Due to the FAT architecture, not all sizes are reachable. Therefore, it
>>>>>>> could be round up to the closest available size.
>>>>>>>
>>>>>>> FAT32 has not been adjusted and thus still default to 504 Mib.
>>>>>>>
>>>>>>> For floppy, only 1440 Kib and 2880 Kib are supported.
>>>>>>>
>>>>>>> Signed-off-by: Clément Chigot <chigot@adacore.com>
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>>>>>>> index 8a479ba090..0bcb360320 100644
>>>>>>> --- a/qapi/block-core.json
>>>>>>> +++ b/qapi/block-core.json
>>>>>>> @@ -3478,11 +3478,17 @@
>>>>>>>  #     (default: true)
>>>>>>>  #     (since 10.2)
>>>>>>>  #
>>>>>>> +# @fat-size: size of the device in bytes.  Due to FAT underlying
>>>>>>> +#     architecture, this size can be rounded up to the closest valid
>>>>>>> +#     size.
>>>>>>> +#     (since 10.2)
>>>>>>> +#
>>>>>>
>>>>>> Can you explain again why you moved from @size to @fat-size?
>>>>>
>>>>> Just to be sure, you mean in the above comment, in the commit message or both ?
>>>>
>>>> Just to me, because I'm not sure I like the change, but that may well be
>>>> due to a lack of understanding of your reasons.
>>>
>>> Naming `fat-size` instead of `size` ensures the parameter is only
>>> recognized by the vvfat backend. In particular, it will be refused by
>>> the default raw format, avoiding confusion:
>>>  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
>>> truncated to 256M, raw format being implicit.
>>>  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
>>> unsupported by raw format.
>>
>> I figure throwing in format=raw to make raw format explicit doesn't
>> change anything.  Correct?
>>
>>>  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
>>>  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
>>> unsupported by vvfat format.
>>
>> If it was called @size, what behavior would we get?  Just two cases, I
>> think:
>>
>> 1. With raw format:
>>
>>     -drive file=fat:<path>,size=256M
>
> You'd silently get a 504 MiB filesystem truncated to 256 MiB (i.e. a
> corrupted file system). It's quite easy to forget format=vvfat, so
> something that initially looks like it might be working is not a great
> result for this user error.

Why doesn't file=fat: imply format=vvfat? For what is the fat: part in 
file then? I currently recommend using:

-drive if=none,id=ufat,format=raw,file=fat:rw:/dir/to/export
-device usb-storage,drive=ufat

to my users which I got from somewhere but don't remember where and it 
seems to work but maybe not the best way to specify this. After reading 
this thread I'm confused about how to use this correctly. Is there some 
documentation on this? There only seems to be some mentions in 
docs/system/qemu-block-drivers.rst.inc but all of them using older 
options:

   |qemu_system| linux.img -hdb fat:/my_directory
   |qemu_system| linux.img -fda fat:floppy:/my_directory
   |qemu_system| linux.img -fda fat:floppy:rw:/my_directory

Regards,
BALATON Zoltan

>> 2. Without raw format:
>>
>>     -drive file=fat:<path>,format=vvfat,size=256M
>
> This does the thing that you actually want, a 256 MiB file system.
>
> I suggested to rename the vvfat option in v1 to make accidents at least
> a bit less likely. I'm not completely sure if "fat-size" is the best
> name, though, as it sounds as if it referred to the FAT itself instead
> of the FAT filesystem. Maybe "fs-size"?
>
> Kevin
>
>
>
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Kevin Wolf 3 days, 22 hours ago
Am 10.11.2025 um 16:36 hat BALATON Zoltan geschrieben:
> On Mon, 10 Nov 2025, Kevin Wolf wrote:
> > Am 10.11.2025 um 14:42 hat Markus Armbruster geschrieben:
> > > Clément Chigot <chigot@adacore.com> writes:
> > > 
> > > > On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
> > > > > 
> > > > > Clément Chigot <chigot@adacore.com> writes:
> > > > > 
> > > > > > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
> > > > > > > 
> > > > > > > Clément Chigot <chigot@adacore.com> writes:
> > > > > > > 
> > > > > > > > This allows more flexibility to vvfat backend. The values of "Number of
> > > > > > > > Heads" and "Sectors per track" are based on SD specifications Part 2.
> > > > > > > > 
> > > > > > > > Due to the FAT architecture, not all sizes are reachable. Therefore, it
> > > > > > > > could be round up to the closest available size.
> > > > > > > > 
> > > > > > > > FAT32 has not been adjusted and thus still default to 504 Mib.
> > > > > > > > 
> > > > > > > > For floppy, only 1440 Kib and 2880 Kib are supported.
> > > > > > > > 
> > > > > > > > Signed-off-by: Clément Chigot <chigot@adacore.com>
> > > > > > > 
> > > > > > > [...]
> > > > > > > 
> > > > > > > > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > > > > > > > index 8a479ba090..0bcb360320 100644
> > > > > > > > --- a/qapi/block-core.json
> > > > > > > > +++ b/qapi/block-core.json
> > > > > > > > @@ -3478,11 +3478,17 @@
> > > > > > > >  #     (default: true)
> > > > > > > >  #     (since 10.2)
> > > > > > > >  #
> > > > > > > > +# @fat-size: size of the device in bytes.  Due to FAT underlying
> > > > > > > > +#     architecture, this size can be rounded up to the closest valid
> > > > > > > > +#     size.
> > > > > > > > +#     (since 10.2)
> > > > > > > > +#
> > > > > > > 
> > > > > > > Can you explain again why you moved from @size to @fat-size?
> > > > > > 
> > > > > > Just to be sure, you mean in the above comment, in the commit message or both ?
> > > > > 
> > > > > Just to me, because I'm not sure I like the change, but that may well be
> > > > > due to a lack of understanding of your reasons.
> > > > 
> > > > Naming `fat-size` instead of `size` ensures the parameter is only
> > > > recognized by the vvfat backend. In particular, it will be refused by
> > > > the default raw format, avoiding confusion:
> > > >  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
> > > > truncated to 256M, raw format being implicit.
> > > >  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
> > > > unsupported by raw format.
> > > 
> > > I figure throwing in format=raw to make raw format explicit doesn't
> > > change anything.  Correct?
> > > 
> > > >  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
> > > >  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
> > > > unsupported by vvfat format.
> > > 
> > > If it was called @size, what behavior would we get?  Just two cases, I
> > > think:
> > > 
> > > 1. With raw format:
> > > 
> > >     -drive file=fat:<path>,size=256M
> > 
> > You'd silently get a 504 MiB filesystem truncated to 256 MiB (i.e. a
> > corrupted file system). It's quite easy to forget format=vvfat, so
> > something that initially looks like it might be working is not a great
> > result for this user error.
> 
> Why doesn't file=fat: imply format=vvfat? For what is the fat: part in
> file then?

-drive is built pretty much on the assumption that you have an image
format that runs on top of a protocol. Format probing probes the image
format, not the protocol, while prefixes like fat: (or nbd:, http: etc.)
specify the protocol.

So if you don't specify the format, we first open the protocol level
(which is vvfat) and then probing will detect that over this protocol,
we access a raw image. So it's mostly like saying format=raw.

I think that format=<protocol driver> works is really more accidental,
but we can't change it now (and probably also don't want to). It results
in opening only the protocol layer and not stacking any format driver on
top of it.

Options that you specify in -drive generally go to the top layer. So the
consequence in our case is that with format=vvfat, the option goes to
vvfat, but with format=raw (or unspecified format), it goes to the raw
forma driver.

> I currently recommend using:
> 
> -drive if=none,id=ufat,format=raw,file=fat:rw:/dir/to/export
> -device usb-storage,drive=ufat
> 
> to my users which I got from somewhere but don't remember where and it
> seems to work but maybe not the best way to specify this.

It's fine, and I might use the same one myself (though you should be
aware that fat:rw: is risky, it's full of bugs).

But if you add an option like size=64M, it goes to the raw driver, which
will take whatever image you access on the protocol level and truncate
it at 64 MiB.

If you want to give the size option on the vvfat level (and create a
filesystem that is actually only 64 MiB instead of truncating a larger
one), then obviously format=vvfat allows you to do that because then
there is no raw format layer to begin with. Or if you do have the raw
format layer, you can access options of the protocol layer by prefixing
"file.". So format=raw,file.size=64M would still pass the size option to
vvfat.

So the command line does allow you to get the option to the right place,
it's just very easy to get confused about this and to specify the option
for the wrong layer.

> After reading this thread I'm confused about how to use this
> correctly. Is there some documentation on this? There only seems to be
> some mentions in docs/system/qemu-block-drivers.rst.inc but all of
> them using older options:
> 
>   |qemu_system| linux.img -hdb fat:/my_directory
>   |qemu_system| linux.img -fda fat:floppy:/my_directory
>   |qemu_system| linux.img -fda fat:floppy:rw:/my_directory

All of those are honestly fine, too, if you're happy with the defaults
and don't want to set more advanced options.

I'll give you this bonus option if you want to be modern:

    -blockdev vvfat,node-name=ufat,dir=/my_directory,rw=on
    -device usb-storage,drive=ufat

But I don't think any of the other options is going away anytime soon.

Kevin


Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Clément Chigot 2 days, 5 hours ago
On Mon, Nov 10, 2025 at 5:31 PM Kevin Wolf <kwolf@redhat.com> wrote:
>
> Am 10.11.2025 um 16:36 hat BALATON Zoltan geschrieben:
> > On Mon, 10 Nov 2025, Kevin Wolf wrote:
> > > Am 10.11.2025 um 14:42 hat Markus Armbruster geschrieben:
> > > > Clément Chigot <chigot@adacore.com> writes:
> > > >
> > > > > On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
> > > > > >
> > > > > > Clément Chigot <chigot@adacore.com> writes:
> > > > > >
> > > > > > > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
> > > > > > > >
> > > > > > > > Clément Chigot <chigot@adacore.com> writes:
> > > > > > > >
> > > > > > > > > This allows more flexibility to vvfat backend. The values of "Number of
> > > > > > > > > Heads" and "Sectors per track" are based on SD specifications Part 2.
> > > > > > > > >
> > > > > > > > > Due to the FAT architecture, not all sizes are reachable. Therefore, it
> > > > > > > > > could be round up to the closest available size.
> > > > > > > > >
> > > > > > > > > FAT32 has not been adjusted and thus still default to 504 Mib.
> > > > > > > > >
> > > > > > > > > For floppy, only 1440 Kib and 2880 Kib are supported.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Clément Chigot <chigot@adacore.com>
> > > > > > > >
> > > > > > > > [...]
> > > > > > > >
> > > > > > > > > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > > > > > > > > index 8a479ba090..0bcb360320 100644
> > > > > > > > > --- a/qapi/block-core.json
> > > > > > > > > +++ b/qapi/block-core.json
> > > > > > > > > @@ -3478,11 +3478,17 @@
> > > > > > > > >  #     (default: true)
> > > > > > > > >  #     (since 10.2)
> > > > > > > > >  #
> > > > > > > > > +# @fat-size: size of the device in bytes.  Due to FAT underlying
> > > > > > > > > +#     architecture, this size can be rounded up to the closest valid
> > > > > > > > > +#     size.
> > > > > > > > > +#     (since 10.2)
> > > > > > > > > +#
> > > > > > > >
> > > > > > > > Can you explain again why you moved from @size to @fat-size?
> > > > > > >
> > > > > > > Just to be sure, you mean in the above comment, in the commit message or both ?
> > > > > >
> > > > > > Just to me, because I'm not sure I like the change, but that may well be
> > > > > > due to a lack of understanding of your reasons.
> > > > >
> > > > > Naming `fat-size` instead of `size` ensures the parameter is only
> > > > > recognized by the vvfat backend. In particular, it will be refused by
> > > > > the default raw format, avoiding confusion:
> > > > >  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
> > > > > truncated to 256M, raw format being implicit.
> > > > >  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
> > > > > unsupported by raw format.
> > > >
> > > > I figure throwing in format=raw to make raw format explicit doesn't
> > > > change anything.  Correct?
> > > >
> > > > >  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
> > > > >  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
> > > > > unsupported by vvfat format.
> > > >
> > > > If it was called @size, what behavior would we get?  Just two cases, I
> > > > think:
> > > >
> > > > 1. With raw format:
> > > >
> > > >     -drive file=fat:<path>,size=256M
> > >
> > > You'd silently get a 504 MiB filesystem truncated to 256 MiB (i.e. a
> > > corrupted file system). It's quite easy to forget format=vvfat, so
> > > something that initially looks like it might be working is not a great
> > > result for this user error.
> >
> > Why doesn't file=fat: imply format=vvfat? For what is the fat: part in
> > file then?
>
> -drive is built pretty much on the assumption that you have an image
> format that runs on top of a protocol. Format probing probes the image
> format, not the protocol, while prefixes like fat: (or nbd:, http: etc.)
> specify the protocol.
>
> So if you don't specify the format, we first open the protocol level
> (which is vvfat) and then probing will detect that over this protocol,
> we access a raw image. So it's mostly like saying format=raw.
>
> I think that format=<protocol driver> works is really more accidental,
> but we can't change it now (and probably also don't want to). It results
> in opening only the protocol layer and not stacking any format driver on
> top of it.
>
> Options that you specify in -drive generally go to the top layer. So the
> consequence in our case is that with format=vvfat, the option goes to
> vvfat, but with format=raw (or unspecified format), it goes to the raw
> forma driver.
>
> > I currently recommend using:
> >
> > -drive if=none,id=ufat,format=raw,file=fat:rw:/dir/to/export
> > -device usb-storage,drive=ufat
> >
> > to my users which I got from somewhere but don't remember where and it
> > seems to work but maybe not the best way to specify this.
>
> It's fine, and I might use the same one myself (though you should be
> aware that fat:rw: is risky, it's full of bugs).
>
> But if you add an option like size=64M, it goes to the raw driver, which
> will take whatever image you access on the protocol level and truncate
> it at 64 MiB.
>
> If you want to give the size option on the vvfat level (and create a
> filesystem that is actually only 64 MiB instead of truncating a larger
> one), then obviously format=vvfat allows you to do that because then
> there is no raw format layer to begin with. Or if you do have the raw
> format layer, you can access options of the protocol layer by prefixing
> "file.". So format=raw,file.size=64M would still pass the size option to
> vvfat.

How is `file.size` working ? I've tried a similar syntax for other
vvfat options (e.g `file.floppy` or the new `file.partitioned`) but
those have no effect. Is this because there are fetched within the
"filename"
Wondering because I'mn ot a fan of the new ":unpartitioned:", I've
added in patch 1. If it can simply be replaced by
`format=raw,file.partitioned=false` or
`format=vvfat,partitioned=false`. I think that would be far enough for
its purpose.

> So the command line does allow you to get the option to the right place,
> it's just very easy to get confused about this and to specify the option
> for the wrong layer.
>
> > After reading this thread I'm confused about how to use this
> > correctly. Is there some documentation on this? There only seems to be
> > some mentions in docs/system/qemu-block-drivers.rst.inc but all of
> > them using older options:
> >
> >   |qemu_system| linux.img -hdb fat:/my_directory
> >   |qemu_system| linux.img -fda fat:floppy:/my_directory
> >   |qemu_system| linux.img -fda fat:floppy:rw:/my_directory
>
> All of those are honestly fine, too, if you're happy with the defaults
> and don't want to set more advanced options.
>
> I'll give you this bonus option if you want to be modern:
>
>     -blockdev vvfat,node-name=ufat,dir=/my_directory,rw=on
>     -device usb-storage,drive=ufat
>
> But I don't think any of the other options is going away anytime soon.
>
> Kevin
>
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Kevin Wolf 2 days, 2 hours ago
Am 12.11.2025 um 10:50 hat Clément Chigot geschrieben:
> On Mon, Nov 10, 2025 at 5:31 PM Kevin Wolf <kwolf@redhat.com> wrote:
> >
> > Am 10.11.2025 um 16:36 hat BALATON Zoltan geschrieben:
> > > On Mon, 10 Nov 2025, Kevin Wolf wrote:
> > > > Am 10.11.2025 um 14:42 hat Markus Armbruster geschrieben:
> > > > > Clément Chigot <chigot@adacore.com> writes:
> > > > >
> > > > > > On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
> > > > > > >
> > > > > > > Clément Chigot <chigot@adacore.com> writes:
> > > > > > >
> > > > > > > > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
> > > > > > > > >
> > > > > > > > > Clément Chigot <chigot@adacore.com> writes:
> > > > > > > > >
> > > > > > > > > > This allows more flexibility to vvfat backend. The values of "Number of
> > > > > > > > > > Heads" and "Sectors per track" are based on SD specifications Part 2.
> > > > > > > > > >
> > > > > > > > > > Due to the FAT architecture, not all sizes are reachable. Therefore, it
> > > > > > > > > > could be round up to the closest available size.
> > > > > > > > > >
> > > > > > > > > > FAT32 has not been adjusted and thus still default to 504 Mib.
> > > > > > > > > >
> > > > > > > > > > For floppy, only 1440 Kib and 2880 Kib are supported.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Clément Chigot <chigot@adacore.com>
> > > > > > > > >
> > > > > > > > > [...]
> > > > > > > > >
> > > > > > > > > > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > > > > > > > > > index 8a479ba090..0bcb360320 100644
> > > > > > > > > > --- a/qapi/block-core.json
> > > > > > > > > > +++ b/qapi/block-core.json
> > > > > > > > > > @@ -3478,11 +3478,17 @@
> > > > > > > > > >  #     (default: true)
> > > > > > > > > >  #     (since 10.2)
> > > > > > > > > >  #
> > > > > > > > > > +# @fat-size: size of the device in bytes.  Due to FAT underlying
> > > > > > > > > > +#     architecture, this size can be rounded up to the closest valid
> > > > > > > > > > +#     size.
> > > > > > > > > > +#     (since 10.2)
> > > > > > > > > > +#
> > > > > > > > >
> > > > > > > > > Can you explain again why you moved from @size to @fat-size?
> > > > > > > >
> > > > > > > > Just to be sure, you mean in the above comment, in the commit message or both ?
> > > > > > >
> > > > > > > Just to me, because I'm not sure I like the change, but that may well be
> > > > > > > due to a lack of understanding of your reasons.
> > > > > >
> > > > > > Naming `fat-size` instead of `size` ensures the parameter is only
> > > > > > recognized by the vvfat backend. In particular, it will be refused by
> > > > > > the default raw format, avoiding confusion:
> > > > > >  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
> > > > > > truncated to 256M, raw format being implicit.
> > > > > >  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
> > > > > > unsupported by raw format.
> > > > >
> > > > > I figure throwing in format=raw to make raw format explicit doesn't
> > > > > change anything.  Correct?
> > > > >
> > > > > >  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
> > > > > >  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
> > > > > > unsupported by vvfat format.
> > > > >
> > > > > If it was called @size, what behavior would we get?  Just two cases, I
> > > > > think:
> > > > >
> > > > > 1. With raw format:
> > > > >
> > > > >     -drive file=fat:<path>,size=256M
> > > >
> > > > You'd silently get a 504 MiB filesystem truncated to 256 MiB (i.e. a
> > > > corrupted file system). It's quite easy to forget format=vvfat, so
> > > > something that initially looks like it might be working is not a great
> > > > result for this user error.
> > >
> > > Why doesn't file=fat: imply format=vvfat? For what is the fat: part in
> > > file then?
> >
> > -drive is built pretty much on the assumption that you have an image
> > format that runs on top of a protocol. Format probing probes the image
> > format, not the protocol, while prefixes like fat: (or nbd:, http: etc.)
> > specify the protocol.
> >
> > So if you don't specify the format, we first open the protocol level
> > (which is vvfat) and then probing will detect that over this protocol,
> > we access a raw image. So it's mostly like saying format=raw.
> >
> > I think that format=<protocol driver> works is really more accidental,
> > but we can't change it now (and probably also don't want to). It results
> > in opening only the protocol layer and not stacking any format driver on
> > top of it.
> >
> > Options that you specify in -drive generally go to the top layer. So the
> > consequence in our case is that with format=vvfat, the option goes to
> > vvfat, but with format=raw (or unspecified format), it goes to the raw
> > forma driver.
> >
> > > I currently recommend using:
> > >
> > > -drive if=none,id=ufat,format=raw,file=fat:rw:/dir/to/export
> > > -device usb-storage,drive=ufat
> > >
> > > to my users which I got from somewhere but don't remember where and it
> > > seems to work but maybe not the best way to specify this.
> >
> > It's fine, and I might use the same one myself (though you should be
> > aware that fat:rw: is risky, it's full of bugs).
> >
> > But if you add an option like size=64M, it goes to the raw driver, which
> > will take whatever image you access on the protocol level and truncate
> > it at 64 MiB.
> >
> > If you want to give the size option on the vvfat level (and create a
> > filesystem that is actually only 64 MiB instead of truncating a larger
> > one), then obviously format=vvfat allows you to do that because then
> > there is no raw format layer to begin with. Or if you do have the raw
> > format layer, you can access options of the protocol layer by prefixing
> > "file.". So format=raw,file.size=64M would still pass the size option to
> > vvfat.
> 
> How is `file.size` working ? I've tried a similar syntax for other
> vvfat options (e.g `file.floppy` or the new `file.partitioned`) but
> those have no effect. Is this because there are fetched within the
> "filename"
> Wondering because I'mn ot a fan of the new ":unpartitioned:", I've
> added in patch 1. If it can simply be replaced by
> `format=raw,file.partitioned=false` or
> `format=vvfat,partitioned=false`. I think that would be far enough for
> its purpose.

Yes, I think it's because vvfat_parse_filename() overwrites them
unconditionally while getting the options from the filename.

Kevin


Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by BALATON Zoltan 3 days, 17 hours ago
On Mon, 10 Nov 2025, Kevin Wolf wrote:
> Am 10.11.2025 um 16:36 hat BALATON Zoltan geschrieben:
>> On Mon, 10 Nov 2025, Kevin Wolf wrote:
>>> Am 10.11.2025 um 14:42 hat Markus Armbruster geschrieben:
>>>> Clément Chigot <chigot@adacore.com> writes:
>>>>
>>>>> On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
>>>>>>
>>>>>> Clément Chigot <chigot@adacore.com> writes:
>>>>>>
>>>>>>> On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
>>>>>>>>
>>>>>>>> Clément Chigot <chigot@adacore.com> writes:
>>>>>>>>
>>>>>>>>> This allows more flexibility to vvfat backend. The values of "Number of
>>>>>>>>> Heads" and "Sectors per track" are based on SD specifications Part 2.
>>>>>>>>>
>>>>>>>>> Due to the FAT architecture, not all sizes are reachable. Therefore, it
>>>>>>>>> could be round up to the closest available size.
>>>>>>>>>
>>>>>>>>> FAT32 has not been adjusted and thus still default to 504 Mib.
>>>>>>>>>
>>>>>>>>> For floppy, only 1440 Kib and 2880 Kib are supported.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Clément Chigot <chigot@adacore.com>
>>>>>>>>
>>>>>>>> [...]
>>>>>>>>
>>>>>>>>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>>>>>>>>> index 8a479ba090..0bcb360320 100644
>>>>>>>>> --- a/qapi/block-core.json
>>>>>>>>> +++ b/qapi/block-core.json
>>>>>>>>> @@ -3478,11 +3478,17 @@
>>>>>>>>>  #     (default: true)
>>>>>>>>>  #     (since 10.2)
>>>>>>>>>  #
>>>>>>>>> +# @fat-size: size of the device in bytes.  Due to FAT underlying
>>>>>>>>> +#     architecture, this size can be rounded up to the closest valid
>>>>>>>>> +#     size.
>>>>>>>>> +#     (since 10.2)
>>>>>>>>> +#
>>>>>>>>
>>>>>>>> Can you explain again why you moved from @size to @fat-size?
>>>>>>>
>>>>>>> Just to be sure, you mean in the above comment, in the commit message or both ?
>>>>>>
>>>>>> Just to me, because I'm not sure I like the change, but that may well be
>>>>>> due to a lack of understanding of your reasons.
>>>>>
>>>>> Naming `fat-size` instead of `size` ensures the parameter is only
>>>>> recognized by the vvfat backend. In particular, it will be refused by
>>>>> the default raw format, avoiding confusion:
>>>>>  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
>>>>> truncated to 256M, raw format being implicit.
>>>>>  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
>>>>> unsupported by raw format.
>>>>
>>>> I figure throwing in format=raw to make raw format explicit doesn't
>>>> change anything.  Correct?
>>>>
>>>>>  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
>>>>>  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
>>>>> unsupported by vvfat format.
>>>>
>>>> If it was called @size, what behavior would we get?  Just two cases, I
>>>> think:
>>>>
>>>> 1. With raw format:
>>>>
>>>>     -drive file=fat:<path>,size=256M
>>>
>>> You'd silently get a 504 MiB filesystem truncated to 256 MiB (i.e. a
>>> corrupted file system). It's quite easy to forget format=vvfat, so
>>> something that initially looks like it might be working is not a great
>>> result for this user error.
>>
>> Why doesn't file=fat: imply format=vvfat? For what is the fat: part in
>> file then?
>
> -drive is built pretty much on the assumption that you have an image
> format that runs on top of a protocol. Format probing probes the image
> format, not the protocol, while prefixes like fat: (or nbd:, http: etc.)
> specify the protocol.

Thanks for clarifying. Is this described somewhere in the docs? The file 
formats are mentioned but the protocol and their relation to formats is 
not clearly described. Maybe it's worth clarifying that in the docs.

> So if you don't specify the format, we first open the protocol level
> (which is vvfat) and then probing will detect that over this protocol,
> we access a raw image. So it's mostly like saying format=raw.

I'm still not sure I completely get this but vvfat is not backed by a raw 
image but a host directory so why is the raw file format comes into play 
here at all? Shouldn't this always assume that for fat: the format is 
vvfat (or no format) and not a raw file? Then size property then would 
also work as expected.

> I think that format=<protocol driver> works is really more accidental,
> but we can't change it now (and probably also don't want to). It results
> in opening only the protocol layer and not stacking any format driver on
> top of it.

Does any format make sense for fat: at all considering the above that it 
does not access an image file with a format but a host directory? So maybe 
using and defaulting to format=raw is not quite right here?

> Options that you specify in -drive generally go to the top layer. So the
> consequence in our case is that with format=vvfat, the option goes to
> vvfat, but with format=raw (or unspecified format), it goes to the raw
> forma driver.

It would work if it would not default to format=raw for fat: which seems 
to make more sense to me than the current default but I don't know if it's 
easy or possible to change that.

>> I currently recommend using:
>>
>> -drive if=none,id=ufat,format=raw,file=fat:rw:/dir/to/export
>> -device usb-storage,drive=ufat
>>
>> to my users which I got from somewhere but don't remember where and it
>> seems to work but maybe not the best way to specify this.
>
> It's fine, and I might use the same one myself (though you should be
> aware that fat:rw: is risky, it's full of bugs).
>
> But if you add an option like size=64M, it goes to the raw driver, which
> will take whatever image you access on the protocol level and truncate
> it at 64 MiB.
>
> If you want to give the size option on the vvfat level (and create a
> filesystem that is actually only 64 MiB instead of truncating a larger
> one), then obviously format=vvfat allows you to do that because then
> there is no raw format layer to begin with. Or if you do have the raw
> format layer, you can access options of the protocol layer by prefixing
> "file.". So format=raw,file.size=64M would still pass the size option to
> vvfat.
>
> So the command line does allow you to get the option to the right place,
> it's just very easy to get confused about this and to specify the option
> for the wrong layer.

In that case maybe it's enough to give a warning in case we detect the 
wrong usage and point users to use the right way to specify size instead 
of adding another fat-size, fs-size or mbr-size option for this? 
Considering that format=vvfat,size=256M works I think either changing the 
default format for fat: or giving an error if fat: and size is specified 
without format=vvfat would solve this without a new option.

Regards,
BALATON Zoltan

>> After reading this thread I'm confused about how to use this
>> correctly. Is there some documentation on this? There only seems to be
>> some mentions in docs/system/qemu-block-drivers.rst.inc but all of
>> them using older options:
>>
>>   |qemu_system| linux.img -hdb fat:/my_directory
>>   |qemu_system| linux.img -fda fat:floppy:/my_directory
>>   |qemu_system| linux.img -fda fat:floppy:rw:/my_directory
>
> All of those are honestly fine, too, if you're happy with the defaults
> and don't want to set more advanced options.
>
> I'll give you this bonus option if you want to be modern:
>
>    -blockdev vvfat,node-name=ufat,dir=/my_directory,rw=on
>    -device usb-storage,drive=ufat
>
> But I don't think any of the other options is going away anytime soon.
>
> Kevin
>
>
Re: [PATCH v2 5/5] vvfat: add support for "fat-size" options
Posted by Clément Chigot 4 days, 1 hour ago
On Mon, Nov 10, 2025 at 2:42 PM Markus Armbruster <armbru@redhat.com> wrote:
>
> Clément Chigot <chigot@adacore.com> writes:
>
> > On Mon, Nov 10, 2025 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
> >>
> >> Clément Chigot <chigot@adacore.com> writes:
> >>
> >> > On Mon, Nov 10, 2025 at 11:13 AM Markus Armbruster <armbru@redhat.com> wrote:
> >> >>
> >> >> Clément Chigot <chigot@adacore.com> writes:
> >> >>
> >> >> > This allows more flexibility to vvfat backend. The values of "Number of
> >> >> > Heads" and "Sectors per track" are based on SD specifications Part 2.
> >> >> >
> >> >> > Due to the FAT architecture, not all sizes are reachable. Therefore, it
> >> >> > could be round up to the closest available size.
> >> >> >
> >> >> > FAT32 has not been adjusted and thus still default to 504 Mib.
> >> >> >
> >> >> > For floppy, only 1440 Kib and 2880 Kib are supported.
> >> >> >
> >> >> > Signed-off-by: Clément Chigot <chigot@adacore.com>
> >> >>
> >> >> [...]
> >> >>
> >> >> > diff --git a/qapi/block-core.json b/qapi/block-core.json
> >> >> > index 8a479ba090..0bcb360320 100644
> >> >> > --- a/qapi/block-core.json
> >> >> > +++ b/qapi/block-core.json
> >> >> > @@ -3478,11 +3478,17 @@
> >> >> >  #     (default: true)
> >> >> >  #     (since 10.2)
> >> >> >  #
> >> >> > +# @fat-size: size of the device in bytes.  Due to FAT underlying
> >> >> > +#     architecture, this size can be rounded up to the closest valid
> >> >> > +#     size.
> >> >> > +#     (since 10.2)
> >> >> > +#
> >> >>
> >> >> Can you explain again why you moved from @size to @fat-size?
> >> >
> >> > Just to be sure, you mean in the above comment, in the commit message or both ?
> >>
> >> Just to me, because I'm not sure I like the change, but that may well be
> >> due to a lack of understanding of your reasons.
> >
> > Naming `fat-size` instead of `size` ensures the parameter is only
> > recognized by the vvfat backend. In particular, it will be refused by
> > the default raw format, avoiding confusion:
> >  "-drive file=fat:<path>,size=256M" results in a 504M FAT disk
> > truncated to 256M, raw format being implicit.
> >  "-drive file=fat:<path>,fat-size=256M" is refused. "fat-size" is
> > unsupported by raw format.
>
> I figure throwing in format=raw to make raw format explicit doesn't
> change anything.  Correct?
>
> >  "-drive file=fat:<path>,format=vvfat,fat-size=256M" results in a 256M FAT disk.
> >  "-drive file=fat:<path>,format=vvfat,size=256M" is refused. "size" is
> > unsupported by vvfat format.
>
> If it was called @size, what behavior would we get?  Just two cases, I
> think:
>
> 1. With raw format:
>
>     -drive file=fat:<path>,size=256M
>
> 2. Without raw format:
>
>     -drive file=fat:<path>,format=vvfat,size=256M

Yes and both result in a FAT system having different sizes. The only
difference being "format=vvfat". When @size is renamed @fat-size, you
are certain to get an error when forgetting that format=vvfat.
Moreover, one could think that one day,
`format=vvfat,size=256M,fat-size=128M` could coexist, creating a 256M
disk with a 128M FAT partition.

Again, I'm not against renaming @size, but I like Kevin's idea to
avoid confusing errors just because you forgot "format".