block: Fix discard alignment calculation and printing
Martin K. Petersen [Mon, 11 Jan 2010 08:21:48 +0000 (03:21 -0500)]
Discard alignment reporting for partitions was incorrect.  Update to
match the algorithm used elsewhere.

The alignment can be negative (misaligned).  Fix format string
accordingly.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

block/genhd.c
include/linux/blkdev.h

index b11a4ad..d13ba76 100644 (file)
@@ -867,7 +867,7 @@ static ssize_t disk_discard_alignment_show(struct device *dev,
 {
        struct gendisk *disk = dev_to_disk(dev);
 
-       return sprintf(buf, "%u\n", queue_discard_alignment(disk->queue));
+       return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue));
 }
 
 static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
index 9b98173..a41bcc8 100644 (file)
@@ -1148,8 +1148,11 @@ static inline int queue_discard_alignment(struct request_queue *q)
 static inline int queue_sector_discard_alignment(struct request_queue *q,
                                                 sector_t sector)
 {
-       return ((sector << 9) - q->limits.discard_alignment)
-               & (q->limits.discard_granularity - 1);
+       struct queue_limits *lim = &q->limits;
+       unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);
+
+       return (lim->discard_granularity + lim->discard_alignment - alignment)
+               & (lim->discard_granularity - 1);
 }
 
 static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)