diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2011-03-11 10:43:35 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-03-14 19:59:57 -0400 |
commit | 32f7ef73585a8773914661e1a8e477e7a0bfa8b4 (patch) | |
tree | df8be2c6f77161127fd73ddfa43f2f7b347aeea6 /drivers/scsi/scsi_debug.c | |
parent | a82058a730c2bd01c43beb8a4847526a2998cc1a (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.c | 9 |
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; |