diff options
| author | Martin K. Petersen <[email protected]> | 2011-05-18 10:37:35 +0200 |
|---|---|---|
| committer | Jens Axboe <[email protected]> | 2011-05-18 10:37:35 +0200 |
| commit | a934a00a69e940b126b9bdbf83e630ef5fe43523 (patch) | |
| tree | b3f82d7b0a6c34c4d449debd2d1d242bdbf84b56 /include | |
| parent | bbdd304cf66fbf2b4b2d28418dc619d443635e83 (diff) | |
block: Fix discard topology stacking and reporting
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 <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Acked-by: Mike Snitzer <[email protected]>
Cc: [email protected]
Signed-off-by: Jens Axboe <[email protected]>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/blkdev.h | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9f921bf4bf8c..520d8618ed76 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -257,7 +257,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 @@ -1069,13 +1069,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; |