Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32f7ef73 authored by Douglas Gilbert's avatar Douglas Gilbert Committed by James Bottomley
Browse files

[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: default avatarDouglas Gilbert <dgilbert@interlog.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent a82058a7
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ static const char * scsi_debug_version_date = "20100324";
/* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
 * sector on read commands: */
#define OPT_MEDIUM_ERR_ADDR   0x1234 /* that's sector 4660 in decimal */
#define OPT_MEDIUM_ERR_NUM    10     /* number of consecutive medium errs */

/* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1)
 * or "peripheral device" addressing (value 0) */
@@ -1807,15 +1808,15 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
		return ret;

	if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
	    (lba <= OPT_MEDIUM_ERR_ADDR) &&
	    (lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) &&
	    ((lba + num) > OPT_MEDIUM_ERR_ADDR)) {
		/* claim unrecoverable read error */
		mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR,
				0);
		mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0);
		/* set info field and valid bit for fixed descriptor */
		if (0x70 == (devip->sense_buff[0] & 0x7f)) {
			devip->sense_buff[0] |= 0x80;	/* Valid bit */
			ret = OPT_MEDIUM_ERR_ADDR;
			ret = (lba < OPT_MEDIUM_ERR_ADDR)
			      ? OPT_MEDIUM_ERR_ADDR : (int)lba;
			devip->sense_buff[3] = (ret >> 24) & 0xff;
			devip->sense_buff[4] = (ret >> 16) & 0xff;
			devip->sense_buff[5] = (ret >> 8) & 0xff;