History

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.

Martin K. Petersen committed 15 years ago

Commit a934a001 parent bbdd3043 files · +9 −4Browse files

Unified · Split

3 files
  1. block/blk-settings.c +2 −1
  2. block/blk-sysfs.c +2 −1
  3. include/linux/blkdev.h +5 −2
block/blk-settings.c+2−1
@@ -120,7 +120,7 @@ void blk_set_default_limits(struct queue_limits *lim) · 119 unmodified lines
120 lim->discard_granularity = 0;120 lim->discard_granularity = 0;
121 lim->discard_alignment = 0;121 lim->discard_alignment = 0;
122 lim->discard_misaligned = 0;122 lim->discard_misaligned = 0;
123 lim->discard_zeroes_data = -1;123 lim->discard_zeroes_data = 1;
124 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;124 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
125 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);125 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
126 lim->alignment_offset = 0;126 lim->alignment_offset = 0;
@@ -166,6 +166,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) · 39 unmodified lines
166 166
167 blk_set_default_limits(&q->limits);167 blk_set_default_limits(&q->limits);
168 blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);168 blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
169 q->limits.discard_zeroes_data = 0;
169 170
170 /*171 /*
171 * by default assume old behaviour and bounce for any highmem page172 * by default assume old behaviour and bounce for any highmem page
block/blk-sysfs.c+2−1
@@ -152,7 +152,8 @@ static ssize_t queue_discard_granularity_show(struct request_queue *q, char *pag · 151 unmodified lines
152 152
153static ssize_t queue_discard_max_show(struct request_queue *q, char *page)153static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
154{154{
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);
156}157}
157 158
158static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)159static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
include/linux/blkdev.h+5−2
@@ -257,7 +257,7 @@ struct queue_limits { · 256 unmodified lines
257 unsigned char misaligned;257 unsigned char misaligned;
258 unsigned char discard_misaligned;258 unsigned char discard_misaligned;
259 unsigned char cluster;259 unsigned char cluster;
260 signed char discard_zeroes_data;260 unsigned char discard_zeroes_data;
261};261};
262 262
263struct request_queue263struct request_queue
@@ -1069,13 +1069,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector · 805 unmodified lines
1069{1069{
1070 unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);1070 unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);
1071 1071
1072 if (!lim->max_discard_sectors)
1073 return 0;
1074
1072 return (lim->discard_granularity + lim->discard_alignment - alignment)1075 return (lim->discard_granularity + lim->discard_alignment - alignment)
1073 & (lim->discard_granularity - 1);1076 & (lim->discard_granularity - 1);
1074}1077}
1075 1078
1076static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)1079static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
1077{1080{
1078 if (q->limits.discard_zeroes_data == 1)1081 if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)
1079 return 1;1082 return 1;
1080 1083
1081 return 0;1084 return 0;