Skip to content

Commit

Permalink
[SCSI] sd: handle bad lba in sense information
Browse files Browse the repository at this point in the history
Some devices report medium error locations incorrectly.  Add guards to
make sure the reported bad lba is actually in the request that caused
it.  Additionally remove the large case statment for sector sizes and
replace it with the proper u64 divisions.

Tested-by: Mike Snitzer <snitzer@gmail.com>
Cc: Stable Tree <stable@kernel.org>
Cc: Tony Battersby <tonyb@cybernetics.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
James Bottomley authored and James Bottomley committed Feb 8, 2008
1 parent d7402cd commit 366c246
Showing 1 changed file with 16 additions and 18 deletions.
34 changes: 16 additions & 18 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
unsigned int xfer_size = scsi_bufflen(SCpnt);
unsigned int good_bytes = result ? 0 : xfer_size;
u64 start_lba = SCpnt->request->sector;
u64 end_lba = SCpnt->request->sector + (xfer_size / 512);
u64 bad_lba;
struct scsi_sense_hdr sshdr;
int sense_valid = 0;
Expand Down Expand Up @@ -967,26 +968,23 @@ static int sd_done(struct scsi_cmnd *SCpnt)
goto out;
if (xfer_size <= SCpnt->device->sector_size)
goto out;
switch (SCpnt->device->sector_size) {
case 256:
if (SCpnt->device->sector_size < 512) {
/* only legitimate sector_size here is 256 */
start_lba <<= 1;
break;
case 512:
break;
case 1024:
start_lba >>= 1;
break;
case 2048:
start_lba >>= 2;
break;
case 4096:
start_lba >>= 3;
break;
default:
/* Print something here with limiting frequency. */
goto out;
break;
end_lba <<= 1;
} else {
/* be careful ... don't want any overflows */
u64 factor = SCpnt->device->sector_size / 512;
do_div(start_lba, factor);
do_div(end_lba, factor);
}

if (bad_lba < start_lba || bad_lba >= end_lba)
/* the bad lba was reported incorrectly, we have
* no idea where the error is
*/
goto out;

/* This computation should always be done in terms of
* the resolution of the device's medium.
*/
Expand Down

0 comments on commit 366c246

Please sign in to comment.