[PATCH] scsi: fix disk capacity too small by one sector

Neil Armstrong neil.armstrong at linaro.org
Mon Oct 14 18:13:30 CEST 2024


On 14/10/2024 18:06, Julius Lehmann wrote:
> SCSI READ CAPACITY reports the address of the last
> block and the block size. The total number of blocks
> is thus last block address plus one.
> 
> ---
> This patch fixes the disk size reported by scsi. Up until now, the reported disk size is too small by one sector. Read/Write operations on other sectors have not been affected. Trying to partition scsi backed storage via ums has resulted in "storage too small" errors.
> 
> doc: https://linux.die.net/man/8/sg_readcap
> 
> Signed-off-by: Julius Lehmann <lehmanju at devpi.de>
> ---
>   drivers/scsi/scsi.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
> index 51cacf3479236be6c6ea3e7d15b87e03f10e7f3a..bcdeda95ed1514119057cc67974fec465cf5672c 100644
> --- a/drivers/scsi/scsi.c
> +++ b/drivers/scsi/scsi.c
> @@ -309,6 +309,7 @@ static int scsi_read_capacity(struct udevice *dev, struct scsi_cmd *pccb,
>   			 ((unsigned long)pccb->pdata[5] << 16) |
>   			 ((unsigned long)pccb->pdata[6] << 8)  |
>   			 ((unsigned long)pccb->pdata[7]);
> +		*capacity += 1;
>   		return 0;
>   	}
>   
> @@ -332,6 +333,7 @@ static int scsi_read_capacity(struct udevice *dev, struct scsi_cmd *pccb,
>   		    ((uint64_t)pccb->pdata[5] << 16) |
>   		    ((uint64_t)pccb->pdata[6] << 8)  |
>   		    ((uint64_t)pccb->pdata[7]);
> +	*capacity += 1;
>   
>   	*blksz = ((uint64_t)pccb->pdata[8]  << 56) |
>   		 ((uint64_t)pccb->pdata[9]  << 48) |
> 
> ---
> base-commit: 29e5dbc55c64c6450f066c55a5bc48bd1717aa1b
> change-id: 20241014-fix-scsi-disksize-d73a017cadf4
> 
> Best regards,

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
Tested-by: Neil Armstrong <neil.armstrong at linaro.org>

Indeed the reported size were quite strange:
- Capacity: 19.9 MB = 0.0 GB (5119 x 4096)
+ Capacity: 20.0 MB = 0.0 GB (5120 x 4096)

Thanks for finding that!

As reported on irc, it's pretty well explained in the sg_readcap man page:
"""
The SCSI READ CAPACITY command (both 10 and 16 byte cdbs) actually yield the
block address of the last block and the block size. The number of blocks is
thus one plus the block address of the last block (as blocks are counted origin
zero (i.e. starting at block zero)). This is the source of many "off by one" errors.
"""

Thanks,
Neil



More information about the U-Boot mailing list