summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_debug.c
diff options
context:
space:
mode:
authorJohn Garry <john.g.garry@oracle.com>2024-10-18 10:16:55 +0000
committerMartin K. Petersen <martin.petersen@oracle.com>2024-10-25 14:48:27 -0400
commitd28d17a845600dd9f7de241de9b1528a1b138716 (patch)
tree2b718c2f42a486cb1d0c21b0eb816ffb6c0b7d3d /drivers/scsi/scsi_debug.c
parentfca6caeb4a61d240f031914413fcc69534f6dc03 (diff)
downloadlwn-d28d17a845600dd9f7de241de9b1528a1b138716.tar.gz
lwn-d28d17a845600dd9f7de241de9b1528a1b138716.zip
scsi: scsi_debug: Fix do_device_access() handling of unexpected SG copy length
If the sg_copy_buffer() call returns less than sdebug_sector_size, then we drop out of the copy loop. However, we still report that we copied the full expected amount, which is not proper. Fix by keeping a running total and return that value. Fixes: 84f3a3c01d70 ("scsi: scsi_debug: Atomic write support") Reported-by: Colin Ian King <colin.i.king@gmail.com> Suggested-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: John Garry <john.g.garry@oracle.com> Link: https://lore.kernel.org/r/20241018101655.4207-1-john.g.garry@oracle.com Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org> Reviewed-by: Colin Ian King <colin.i.king@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r--drivers/scsi/scsi_debug.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index d95f417e24c0..9be2a6a00530 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3651,7 +3651,7 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp,
enum dma_data_direction dir;
struct scsi_data_buffer *sdb = &scp->sdb;
u8 *fsp;
- int i;
+ int i, total = 0;
/*
* Even though reads are inherently atomic (in this driver), we expect
@@ -3688,18 +3688,16 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp,
fsp + (block * sdebug_sector_size),
sdebug_sector_size, sg_skip, do_write);
sdeb_data_sector_unlock(sip, do_write);
- if (ret != sdebug_sector_size) {
- ret += (i * sdebug_sector_size);
+ total += ret;
+ if (ret != sdebug_sector_size)
break;
- }
sg_skip += sdebug_sector_size;
if (++block >= sdebug_store_sectors)
block = 0;
}
- ret = num * sdebug_sector_size;
sdeb_data_unlock(sip, atomic);
- return ret;
+ return total;
}
/* Returns number of bytes copied or -1 if error. */