aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/blk-settings.c46
-rw-r--r--block/blk-sysfs.c22
-rw-r--r--block/genhd.c12
3 files changed, 70 insertions, 10 deletions
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 66d4aa8799b7..7f986cafacd5 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -96,7 +96,10 @@ void blk_set_default_limits(struct queue_limits *lim)
96 lim->max_segment_size = MAX_SEGMENT_SIZE; 96 lim->max_segment_size = MAX_SEGMENT_SIZE;
97 lim->max_sectors = BLK_DEF_MAX_SECTORS; 97 lim->max_sectors = BLK_DEF_MAX_SECTORS;
98 lim->max_hw_sectors = INT_MAX; 98 lim->max_hw_sectors = INT_MAX;
99 lim->max_discard_sectors = SAFE_MAX_SECTORS; 99 lim->max_discard_sectors = 0;
100 lim->discard_granularity = 0;
101 lim->discard_alignment = 0;
102 lim->discard_misaligned = 0;
100 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; 103 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
101 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); 104 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
102 lim->alignment_offset = 0; 105 lim->alignment_offset = 0;
@@ -488,6 +491,16 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
488} 491}
489EXPORT_SYMBOL(blk_queue_stack_limits); 492EXPORT_SYMBOL(blk_queue_stack_limits);
490 493
494static unsigned int lcm(unsigned int a, unsigned int b)
495{
496 if (a && b)
497 return (a * b) / gcd(a, b);
498 else if (b)
499 return b;
500
501 return a;
502}
503
491/** 504/**
492 * blk_stack_limits - adjust queue_limits for stacked devices 505 * blk_stack_limits - adjust queue_limits for stacked devices
493 * @t: the stacking driver limits (top) 506 * @t: the stacking driver limits (top)
@@ -502,6 +515,10 @@ EXPORT_SYMBOL(blk_queue_stack_limits);
502int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, 515int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
503 sector_t offset) 516 sector_t offset)
504{ 517{
518 int ret;
519
520 ret = 0;
521
505 t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); 522 t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
506 t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); 523 t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
507 t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn); 524 t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn);
@@ -531,7 +548,13 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
531 if (offset && 548 if (offset &&
532 (offset & (b->physical_block_size - 1)) != b->alignment_offset) { 549 (offset & (b->physical_block_size - 1)) != b->alignment_offset) {
533 t->misaligned = 1; 550 t->misaligned = 1;
534 return -1; 551 ret = -1;
552 }
553
554 if (offset &&
555 (offset & (b->discard_granularity - 1)) != b->discard_alignment) {
556 t->discard_misaligned = 1;
557 ret = -1;
535 } 558 }
536 559
537 /* If top has no alignment offset, inherit from bottom */ 560 /* If top has no alignment offset, inherit from bottom */
@@ -539,23 +562,26 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
539 t->alignment_offset = 562 t->alignment_offset =
540 b->alignment_offset & (b->physical_block_size - 1); 563 b->alignment_offset & (b->physical_block_size - 1);
541 564
565 if (!t->discard_alignment)
566 t->discard_alignment =
567 b->discard_alignment & (b->discard_granularity - 1);
568
542 /* Top device aligned on logical block boundary? */ 569 /* Top device aligned on logical block boundary? */
543 if (t->alignment_offset & (t->logical_block_size - 1)) { 570 if (t->alignment_offset & (t->logical_block_size - 1)) {
544 t->misaligned = 1; 571 t->misaligned = 1;
545 return -1; 572 ret = -1;
546 } 573 }
547 574
548 /* Find lcm() of optimal I/O size */ 575 /* Find lcm() of optimal I/O size and granularity */
549 if (t->io_opt && b->io_opt) 576 t->io_opt = lcm(t->io_opt, b->io_opt);
550 t->io_opt = (t->io_opt * b->io_opt) / gcd(t->io_opt, b->io_opt); 577 t->discard_granularity = lcm(t->discard_granularity,
551 else if (b->io_opt) 578 b->discard_granularity);
552 t->io_opt = b->io_opt;
553 579
554 /* Verify that optimal I/O size is a multiple of io_min */ 580 /* Verify that optimal I/O size is a multiple of io_min */
555 if (t->io_min && t->io_opt % t->io_min) 581 if (t->io_min && t->io_opt % t->io_min)
556 return -1; 582 ret = -1;
557 583
558 return 0; 584 return ret;
559} 585}
560EXPORT_SYMBOL(blk_stack_limits); 586EXPORT_SYMBOL(blk_stack_limits);
561 587
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 8a6d81afb284..3147145edc15 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -126,6 +126,16 @@ static ssize_t queue_io_opt_show(struct request_queue *q, char *page)
126 return queue_var_show(queue_io_opt(q), page); 126 return queue_var_show(queue_io_opt(q), page);
127} 127}
128 128
129static ssize_t queue_discard_granularity_show(struct request_queue *q, char *page)
130{
131 return queue_var_show(q->limits.discard_granularity, page);
132}
133
134static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
135{
136 return queue_var_show(q->limits.max_discard_sectors << 9, page);
137}
138
129static ssize_t 139static ssize_t
130queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) 140queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
131{ 141{
@@ -293,6 +303,16 @@ static struct queue_sysfs_entry queue_io_opt_entry = {
293 .show = queue_io_opt_show, 303 .show = queue_io_opt_show,
294}; 304};
295 305
306static struct queue_sysfs_entry queue_discard_granularity_entry = {
307 .attr = {.name = "discard_granularity", .mode = S_IRUGO },
308 .show = queue_discard_granularity_show,
309};
310
311static struct queue_sysfs_entry queue_discard_max_entry = {
312 .attr = {.name = "discard_max_bytes", .mode = S_IRUGO },
313 .show = queue_discard_max_show,
314};
315
296static struct queue_sysfs_entry queue_nonrot_entry = { 316static struct queue_sysfs_entry queue_nonrot_entry = {
297 .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR }, 317 .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
298 .show = queue_nonrot_show, 318 .show = queue_nonrot_show,
@@ -328,6 +348,8 @@ static struct attribute *default_attrs[] = {
328 &queue_physical_block_size_entry.attr, 348 &queue_physical_block_size_entry.attr,
329 &queue_io_min_entry.attr, 349 &queue_io_min_entry.attr,
330 &queue_io_opt_entry.attr, 350 &queue_io_opt_entry.attr,
351 &queue_discard_granularity_entry.attr,
352 &queue_discard_max_entry.attr,
331 &queue_nonrot_entry.attr, 353 &queue_nonrot_entry.attr,
332 &queue_nomerges_entry.attr, 354 &queue_nomerges_entry.attr,
333 &queue_rq_affinity_entry.attr, 355 &queue_rq_affinity_entry.attr,
diff --git a/block/genhd.c b/block/genhd.c
index 517e4332cb37..b11a4ad7d571 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -861,12 +861,23 @@ static ssize_t disk_alignment_offset_show(struct device *dev,
861 return sprintf(buf, "%d\n", queue_alignment_offset(disk->queue)); 861 return sprintf(buf, "%d\n", queue_alignment_offset(disk->queue));
862} 862}
863 863
864static ssize_t disk_discard_alignment_show(struct device *dev,
865 struct device_attribute *attr,
866 char *buf)
867{
868 struct gendisk *disk = dev_to_disk(dev);
869
870 return sprintf(buf, "%u\n", queue_discard_alignment(disk->queue));
871}
872
864static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); 873static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
865static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL); 874static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
866static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); 875static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
867static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL); 876static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
868static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); 877static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
869static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL); 878static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
879static DEVICE_ATTR(discard_alignment, S_IRUGO, disk_discard_alignment_show,
880 NULL);
870static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); 881static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
871static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); 882static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
872static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); 883static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
@@ -887,6 +898,7 @@ static struct attribute *disk_attrs[] = {
887 &dev_attr_ro.attr, 898 &dev_attr_ro.attr,
888 &dev_attr_size.attr, 899 &dev_attr_size.attr,
889 &dev_attr_alignment_offset.attr, 900 &dev_attr_alignment_offset.attr,
901 &dev_attr_discard_alignment.attr,
890 &dev_attr_capability.attr, 902 &dev_attr_capability.attr,
891 &dev_attr_stat.attr, 903 &dev_attr_stat.attr,
892 &dev_attr_inflight.attr, 904 &dev_attr_inflight.attr,