With module parameter virtual_gb > 0, the device accesses may go beyond the actual ramdisk storage (fake_storep). Such requests should be treated as fake_storep is repeatedly mirrored up to virtual size (virtual_gb * 1GB). Unfortunately, WRITE_SAME commands with such requests access out of fake_storep region. For writing to the first LBA, this fixes it by switching to use existing do_device_access() which does the correct conversion of LBA. For spreading the first LBA over the remaining blocks, this fixes it by using newly introduced fake_store() for getting valid address which is corresponding to a given LBA in fake_storep. Signed-off-by: Akinobu Mita <akinobu.mita@xxxxxxxxx> Cc: "James E.J. Bottomley" <JBottomley@xxxxxxxxxxxxx> Cc: Douglas Gilbert <dgilbert@xxxxxxxxxxxx> Cc: "Martin K. Petersen" <martin.petersen@xxxxxxxxxx> Cc: linux-scsi@xxxxxxxxxxxxxxx --- drivers/scsi/scsi_debug.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 01c0ffa..1e25c1e 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -257,7 +257,7 @@ struct sdebug_queued_cmd { }; static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; -static unsigned char * fake_storep; /* ramdisk storage */ +static void *fake_storep; /* ramdisk storage */ static struct sd_dif_tuple *dif_storep; /* protection info */ static void *map_storep; /* provisioning map */ @@ -293,6 +293,13 @@ static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x0}; +static void *fake_store(unsigned long long lba) +{ + lba = do_div(lba, sdebug_store_sectors); + + return fake_storep + lba * scsi_debug_sector_size; +} + static int sdebug_add_adapter(void); static void sdebug_remove_adapter(void); @@ -2131,9 +2138,7 @@ static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, } /* Else fetch one logical block */ - ret = fetch_to_dev_buffer(scmd, - fake_storep + (lba * scsi_debug_sector_size), - scsi_debug_sector_size); + ret = do_device_access(scmd, devip, lba, 1, 1); if (-1 == ret) { write_unlock_irqrestore(&atomic_rw, iflags); @@ -2145,8 +2150,7 @@ static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, /* Copy first sector to remaining blocks */ for (i = 1 ; i < num ; i++) - memcpy(fake_storep + ((lba + i) * scsi_debug_sector_size), - fake_storep + (lba * scsi_debug_sector_size), + memcpy(fake_store(lba + i), fake_store(lba), scsi_debug_sector_size); if (scsi_debug_lbp()) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html