libata: fix off-by-one error in ata_tf_read_block()
authorTejun Heo <htejun@gmail.com>
Sun, 16 Aug 2009 12:21:21 +0000 (21:21 +0900)
committerJeff Garzik <jgarzik@redhat.com>
Wed, 9 Sep 2009 01:18:03 +0000 (21:18 -0400)
ata_tf_read_block() has off-by-one error when converting CHS address
to LBA.  The bug isn't very visible because ata_tf_read_block() is
used only when generating sense data for a failed RW command and CHS
addressing isn't used too often these days.

This problem was spotted by Atsushi Nemoto.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/ata/libata-core.c

index 98af50f16e0cc4d801ca7a70923831c6a8885a19..df31deac5c8224fce9e4e0571c4484d35d966966 100644 (file)
@@ -709,7 +709,13 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
                head = tf->device & 0xf;
                sect = tf->lbal;
 
-               block = (cyl * dev->heads + head) * dev->sectors + sect;
+               if (!sect) {
+                       ata_dev_printk(dev, KERN_WARNING, "device reported "
+                                      "invalid CHS sector 0\n");
+                       sect = 1; /* oh well */
+               }
+
+               block = (cyl * dev->heads + head) * dev->sectors + sect - 1;
        }
 
        return block;