summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2011-05-18 10:37:35 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-03 10:33:44 +0900
commit5d8ddba27676c7f753b01ac75f90ea90be0ffcea (patch)
tree6d9470748405d37ea71ceef1c94e95e71b9b641a /include
parentc63356c3ed12f1242ec7fb4b14a6a28b0e0c72a2 (diff)
block: Fix discard topology stacking and reporting
commit a934a00a69e940b126b9bdbf83e630ef5fe43523 upstream. In some cases we would end up stacking discard_zeroes_data incorrectly. Fix this by enabling the feature by default for stacking drivers and clearing it for low-level drivers. Incorporating a device that does not support dzd will then cause the feature to be disabled in the stacking driver. Also ensure that the maximum discard value does not overflow when exported in sysfs and return 0 in the alignment and dzd fields for devices that don't support discard. Reported-by: Lukas Czerner <lczerner@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Acked-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/blkdev.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d5063e1b5555..65661479a232 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -252,7 +252,7 @@ struct queue_limits {
unsigned char misaligned;
unsigned char discard_misaligned;
unsigned char cluster;
- signed char discard_zeroes_data;
+ unsigned char discard_zeroes_data;
};
struct request_queue
@@ -1032,13 +1032,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector
{
unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);
+ if (!lim->max_discard_sectors)
+ return 0;
+
return (lim->discard_granularity + lim->discard_alignment - alignment)
& (lim->discard_granularity - 1);
}
static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
{
- if (q->limits.discard_zeroes_data == 1)
+ if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)
return 1;
return 0;