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

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@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,

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@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]);
return 0; }*capacity += 1;
@@ -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@linaro.org Tested-by: Neil Armstrong neil.armstrong@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

On Mon, Oct 14, 2024 at 06:06:35PM +0200, 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@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]);
return 0; }*capacity += 1;
@@ -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) |
This leads to this failure in CI: https://source.denx.de/u-boot/u-boot/-/jobs/926468#L288

Am 22.10.2024 um 05:35 schrieb Tom Rini trini@konsulko.com:
On Mon, Oct 14, 2024 at 06:06:35PM +0200, 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@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) |
This leads to this failure in CI: https://source.denx.de/u-boot/u-boot/-/jobs/926468#L288
thx for the hint. looks like the test might need some updating, since the expected output has changed. will fix it with the next iteration … once i fixed all the necessary python dependencies to run the test locally
-- Tom <signature.asc>
Regards Julius
participants (3)
-
Julius Lehmann
-
Neil Armstrong
-
Tom Rini