Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=366c246de9cec909c5eba4f784c92d1e75b4dc38
Commit:     366c246de9cec909c5eba4f784c92d1e75b4dc38
Parent:     d7402cd91022fc32522397d3930a3e6587de7c55
Author:     James Bottomley <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 2 16:06:23 2008 -0600
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Thu Feb 7 18:02:41 2008 -0600

    [SCSI] sd: handle bad lba in sense information
    
    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 <[EMAIL PROTECTED]>
    Cc: Stable Tree <[EMAIL PROTECTED]>
    Cc: Tony Battersby <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/sd.c |   34 ++++++++++++++++------------------
 1 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 51a5557..37df8bb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -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;
@@ -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.
                 */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to