aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_debug.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2011-03-11 10:43:35 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-03-14 19:59:57 -0400
commit32f7ef73585a8773914661e1a8e477e7a0bfa8b4 (patch)
treedf8be2c6f77161127fd73ddfa43f2f7b347aeea6 /drivers/scsi/scsi_debug.c
parenta82058a730c2bd01c43beb8a4847526a2998cc1a (diff)
[SCSI] scsi_debug: add consecutive medium errors
A useful test case for error recovery is multiple, consecutive medium errors. When scsi_debug is started with "opts=2" a MEDIUM ERROR is generated when block 0x1234 (4660) is read. The patch extends that to 10 consecutive blocks from 0x1234 (i.e. blocks 4660 to 4669 inclusive). [0:0:0:0] disk ATA INTEL SSD 2CV1 /dev/sda /dev/sg0 80.0GB [10:0:0:0] disk Linux scsi_debug 0004 /dev/sdb /dev/sg1 1.09TB Output file not specified so no copy, just reading input >> unrecovered read error at blk=4660, substitute zeros ... >> unrecovered read error at blk=4669, substitute zeros 4670+10 records in 0+0 records out 10 unrecovered read errors lowest unrecovered read lba=4660, highest unrecovered lba=4669 time to read data: 0.047943 secs at 49.87 MB/sec BTW Change /dev/sg1 (bsg device works just as well) to /dev/sdb to see why, with faulty media, you do not want to use the block layer interface. Reason: time block layer takes to do useless retries and collateral damage to data in its 4 KB blocks (O_DIRECT mitigates the latter). ChangeLog: - extend opts=2 medium error generation at block 0x1234 to 10 consecutive blocks (i.e. blocks 0x1234 to 0x123d). Signed-off-by: Douglas Gilbert <dgilbert@interlog.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r--drivers/scsi/scsi_debug.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 6ba5dbb91096..1829648982be 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -146,6 +146,7 @@ static const char * scsi_debug_version_date = "20100324";
146/* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this 146/* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
147 * sector on read commands: */ 147 * sector on read commands: */
148#define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */ 148#define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */
149#define OPT_MEDIUM_ERR_NUM 10 /* number of consecutive medium errs */
149 150
150/* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) 151/* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1)
151 * or "peripheral device" addressing (value 0) */ 152 * or "peripheral device" addressing (value 0) */
@@ -1807,15 +1808,15 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
1807 return ret; 1808 return ret;
1808 1809
1809 if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && 1810 if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
1810 (lba <= OPT_MEDIUM_ERR_ADDR) && 1811 (lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) &&
1811 ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { 1812 ((lba + num) > OPT_MEDIUM_ERR_ADDR)) {
1812 /* claim unrecoverable read error */ 1813 /* claim unrecoverable read error */
1813 mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 1814 mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0);
1814 0);
1815 /* set info field and valid bit for fixed descriptor */ 1815 /* set info field and valid bit for fixed descriptor */
1816 if (0x70 == (devip->sense_buff[0] & 0x7f)) { 1816 if (0x70 == (devip->sense_buff[0] & 0x7f)) {
1817 devip->sense_buff[0] |= 0x80; /* Valid bit */ 1817 devip->sense_buff[0] |= 0x80; /* Valid bit */
1818 ret = OPT_MEDIUM_ERR_ADDR; 1818 ret = (lba < OPT_MEDIUM_ERR_ADDR)
1819 ? OPT_MEDIUM_ERR_ADDR : (int)lba;
1819 devip->sense_buff[3] = (ret >> 24) & 0xff; 1820 devip->sense_buff[3] = (ret >> 24) & 0xff;
1820 devip->sense_buff[4] = (ret >> 16) & 0xff; 1821 devip->sense_buff[4] = (ret >> 16) & 0xff;
1821 devip->sense_buff[5] = (ret >> 8) & 0xff; 1822 devip->sense_buff[5] = (ret >> 8) & 0xff;