Skip to content

Commit

Permalink
block: Fix discard topology stacking and reporting
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
martinkpetersen authored and Jens Axboe committed May 18, 2011
1 parent bbdd304 commit a934a00
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 4 deletions.
3 changes: 2 additions & 1 deletion block/blk-settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->discard_granularity = 0;
lim->discard_alignment = 0;
lim->discard_misaligned = 0;
lim->discard_zeroes_data = -1;
lim->discard_zeroes_data = 1;
lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
lim->alignment_offset = 0;
Expand Down Expand Up @@ -166,6 +166,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)

blk_set_default_limits(&q->limits);
blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
q->limits.discard_zeroes_data = 0;

/*
* by default assume old behaviour and bounce for any highmem page
Expand Down
3 changes: 2 additions & 1 deletion block/blk-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ static ssize_t queue_discard_granularity_show(struct request_queue *q, char *pag

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

static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
Expand Down
7 changes: 5 additions & 2 deletions include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a934a00

Please sign in to comment.