[PATCH 1/9] fs/fat/fat.c: Do not perform zero block reads if there are no blocks left
Heinrich Schuchardt
xypron.debian at gmx.de
Sat Jul 25 17:27:38 CEST 2020
On 7/24/20 11:50 PM, Jason Wessel wrote:
> While using u-boot with qemu's virtio driver I stumbled across a
> problem reading files less than sector size. On the real hardware the
> block reader seems ok with reading zero blocks, and while we could fix
> the virtio host side of qemu to deal with a zero block read instead of
> crashing, the u-boot fat driver should not be doing zero block reads
> in the first place. If you ask hardware to read zero blocks you are
> just going to get zero data. There may also be other hardware that
> responds similarly to the virtio interface so this is worth fixing.
>
> Without the patch I get the following and have to restart qemu because
> it dies.
Our block drivers all have a different view on this:
mmc_read_blocks() is reading one block even if 0 blocks are requested.
scsi_setup_read16() happily passes the 0 to the controller.
I think blk_read_devnum(), blk_write_devnum(), blk_dread(), and
blk_dwrite() is where we need the block count check.
> ---------------------------------
> => fatls virtio 0:1
> 30 cmdline.txt
> => fatload virtio 0:1 ${loadaddr} cmdline.txt
> qemu-system-aarch64: virtio: zero sized buffers are not allowed
> ---------------------------------
>
> With the patch I get the expected results.
> ---------------------------------
> => fatls virtio 0:1
> 30 cmdline.txt
> => fatload virtio 0:1 ${loadaddr} cmdline.txt
> 30 bytes read in 11 ms (2 KiB/s)
> => md.b ${loadaddr} 0x1E
> 40080000: 64 77 63 5f 6f 74 67 2e 6c 70 6d 5f 65 6e 61 62 dwc_otg.lpm_enab
> 40080010: 6c 65 3d 30 20 72 6f 6f 74 77 61 69 74 0a le=0 rootwait.
>
> ---------------------------------
>
> Signed-off-by: Jason Wessel <jason.wessel at windriver.com>
> Reviewed-by: Tom Rini <trini at konsulko.com>
> ---
> fs/fat/fat.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> index 9578b74bae..28aa5aaa9f 100644
> --- a/fs/fat/fat.c
> +++ b/fs/fat/fat.c
> @@ -278,7 +278,10 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size)
> }
> } else {
> idx = size / mydata->sect_size;
> - ret = disk_read(startsect, idx, buffer);
> + if (idx == 0)
> + ret = 0;
> + else
> + ret = disk_read(startsect, idx, buffer);
Using idx as variable name here for a block count is quite misleading.
Best regards
Heinrich
> if (ret != idx) {
> debug("Error reading data (got %d)\n", ret);
> return -1;
>
More information about the U-Boot
mailing list