Skip to content

Commit a934a00

Browse files
martinkpetersenJens Axboe
authored andcommitted
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 <lczerner@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Acked-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@kernel.org Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
1 parent bbdd304 commit a934a00

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

block/blk-settings.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void blk_set_default_limits(struct queue_limits *lim)
120120
lim->discard_granularity = 0;
121121
lim->discard_alignment = 0;
122122
lim->discard_misaligned = 0;
123-
lim->discard_zeroes_data = -1;
123+
lim->discard_zeroes_data = 1;
124124
lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
125125
lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
126126
lim->alignment_offset = 0;
@@ -166,6 +166,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
166166

167167
blk_set_default_limits(&q->limits);
168168
blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
169+
q->limits.discard_zeroes_data = 0;
169170

170171
/*
171172
* by default assume old behaviour and bounce for any highmem page

block/blk-sysfs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ static ssize_t queue_discard_granularity_show(struct request_queue *q, char *pag
152152

153153
static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
154154
{
155-
return queue_var_show(q->limits.max_discard_sectors << 9, page);
155+
return sprintf(page, "%llu\n",
156+
(unsigned long long)q->limits.max_discard_sectors << 9);
156157
}
157158

158159
static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)

include/linux/blkdev.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ struct queue_limits {
257257
unsigned char misaligned;
258258
unsigned char discard_misaligned;
259259
unsigned char cluster;
260-
signed char discard_zeroes_data;
260+
unsigned char discard_zeroes_data;
261261
};
262262

263263
struct request_queue
@@ -1069,13 +1069,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector
10691069
{
10701070
unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);
10711071

1072+
if (!lim->max_discard_sectors)
1073+
return 0;
1074+
10721075
return (lim->discard_granularity + lim->discard_alignment - alignment)
10731076
& (lim->discard_granularity - 1);
10741077
}
10751078

10761079
static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
10771080
{
1078-
if (q->limits.discard_zeroes_data == 1)
1081+
if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)
10791082
return 1;
10801083

10811084
return 0;

0 commit comments

Comments
 (0)