diff options
-rw-r--r-- | block/blk-settings.c | 26 | ||||
-rw-r--r-- | fs/partitions/check.c | 7 | ||||
-rw-r--r-- | include/linux/blkdev.h | 17 |
3 files changed, 18 insertions, 32 deletions
diff --git a/block/blk-settings.c b/block/blk-settings.c index 5eeb9e0d256e..78549c723783 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -507,7 +507,7 @@ static unsigned int lcm(unsigned int a, unsigned int b) | |||
507 | * blk_stack_limits - adjust queue_limits for stacked devices | 507 | * blk_stack_limits - adjust queue_limits for stacked devices |
508 | * @t: the stacking driver limits (top device) | 508 | * @t: the stacking driver limits (top device) |
509 | * @b: the underlying queue limits (bottom, component device) | 509 | * @b: the underlying queue limits (bottom, component device) |
510 | * @offset: offset to beginning of data within component device | 510 | * @start: first data sector within component device |
511 | * | 511 | * |
512 | * Description: | 512 | * Description: |
513 | * This function is used by stacking drivers like MD and DM to ensure | 513 | * This function is used by stacking drivers like MD and DM to ensure |
@@ -525,10 +525,9 @@ static unsigned int lcm(unsigned int a, unsigned int b) | |||
525 | * the alignment_offset is undefined. | 525 | * the alignment_offset is undefined. |
526 | */ | 526 | */ |
527 | int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | 527 | int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, |
528 | sector_t offset) | 528 | sector_t start) |
529 | { | 529 | { |
530 | sector_t alignment; | 530 | unsigned int top, bottom, alignment, ret = 0; |
531 | unsigned int top, bottom, ret = 0; | ||
532 | 531 | ||
533 | t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); | 532 | t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); |
534 | t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); | 533 | t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); |
@@ -548,7 +547,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
548 | 547 | ||
549 | t->misaligned |= b->misaligned; | 548 | t->misaligned |= b->misaligned; |
550 | 549 | ||
551 | alignment = queue_limit_alignment_offset(b, offset); | 550 | alignment = queue_limit_alignment_offset(b, start); |
552 | 551 | ||
553 | /* Bottom device has different alignment. Check that it is | 552 | /* Bottom device has different alignment. Check that it is |
554 | * compatible with the current top alignment. | 553 | * compatible with the current top alignment. |
@@ -611,11 +610,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
611 | 610 | ||
612 | /* Discard alignment and granularity */ | 611 | /* Discard alignment and granularity */ |
613 | if (b->discard_granularity) { | 612 | if (b->discard_granularity) { |
614 | unsigned int granularity = b->discard_granularity; | 613 | alignment = queue_limit_discard_alignment(b, start); |
615 | offset &= granularity - 1; | ||
616 | |||
617 | alignment = (granularity + b->discard_alignment - offset) | ||
618 | & (granularity - 1); | ||
619 | 614 | ||
620 | if (t->discard_granularity != 0 && | 615 | if (t->discard_granularity != 0 && |
621 | t->discard_alignment != alignment) { | 616 | t->discard_alignment != alignment) { |
@@ -657,7 +652,7 @@ int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev, | |||
657 | 652 | ||
658 | start += get_start_sect(bdev); | 653 | start += get_start_sect(bdev); |
659 | 654 | ||
660 | return blk_stack_limits(t, &bq->limits, start << 9); | 655 | return blk_stack_limits(t, &bq->limits, start); |
661 | } | 656 | } |
662 | EXPORT_SYMBOL(bdev_stack_limits); | 657 | EXPORT_SYMBOL(bdev_stack_limits); |
663 | 658 | ||
@@ -668,9 +663,8 @@ EXPORT_SYMBOL(bdev_stack_limits); | |||
668 | * @offset: offset to beginning of data within component device | 663 | * @offset: offset to beginning of data within component device |
669 | * | 664 | * |
670 | * Description: | 665 | * Description: |
671 | * Merges the limits for two queues. Returns 0 if alignment | 666 | * Merges the limits for a top level gendisk and a bottom level |
672 | * didn't change. Returns -1 if adding the bottom device caused | 667 | * block_device. |
673 | * misalignment. | ||
674 | */ | 668 | */ |
675 | void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | 669 | void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, |
676 | sector_t offset) | 670 | sector_t offset) |
@@ -678,9 +672,7 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | |||
678 | struct request_queue *t = disk->queue; | 672 | struct request_queue *t = disk->queue; |
679 | struct request_queue *b = bdev_get_queue(bdev); | 673 | struct request_queue *b = bdev_get_queue(bdev); |
680 | 674 | ||
681 | offset += get_start_sect(bdev) << 9; | 675 | if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) { |
682 | |||
683 | if (blk_stack_limits(&t->limits, &b->limits, offset) < 0) { | ||
684 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; | 676 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; |
685 | 677 | ||
686 | disk_name(disk, 0, top); | 678 | disk_name(disk, 0, top); |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 64bc8998ac9a..e8865c11777f 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -412,9 +412,10 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
412 | pdev = part_to_dev(p); | 412 | pdev = part_to_dev(p); |
413 | 413 | ||
414 | p->start_sect = start; | 414 | p->start_sect = start; |
415 | p->alignment_offset = queue_sector_alignment_offset(disk->queue, start); | 415 | p->alignment_offset = |
416 | p->discard_alignment = queue_sector_discard_alignment(disk->queue, | 416 | queue_limit_alignment_offset(&disk->queue->limits, start); |
417 | start); | 417 | p->discard_alignment = |
418 | queue_limit_discard_alignment(&disk->queue->limits, start); | ||
418 | p->nr_sects = len; | 419 | p->nr_sects = len; |
419 | p->partno = partno; | 420 | p->partno = partno; |
420 | p->policy = get_disk_ro(disk); | 421 | p->policy = get_disk_ro(disk); |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 5c8018977efa..ffb13ad35716 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1112,18 +1112,13 @@ static inline int queue_alignment_offset(struct request_queue *q) | |||
1112 | return q->limits.alignment_offset; | 1112 | return q->limits.alignment_offset; |
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t offset) | 1115 | static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t sector) |
1116 | { | 1116 | { |
1117 | unsigned int granularity = max(lim->physical_block_size, lim->io_min); | 1117 | unsigned int granularity = max(lim->physical_block_size, lim->io_min); |
1118 | unsigned int alignment = (sector << 9) & (granularity - 1); | ||
1118 | 1119 | ||
1119 | offset &= granularity - 1; | 1120 | return (granularity + lim->alignment_offset - alignment) |
1120 | return (granularity + lim->alignment_offset - offset) & (granularity - 1); | 1121 | & (granularity - 1); |
1121 | } | ||
1122 | |||
1123 | static inline int queue_sector_alignment_offset(struct request_queue *q, | ||
1124 | sector_t sector) | ||
1125 | { | ||
1126 | return queue_limit_alignment_offset(&q->limits, sector << 9); | ||
1127 | } | 1122 | } |
1128 | 1123 | ||
1129 | static inline int bdev_alignment_offset(struct block_device *bdev) | 1124 | static inline int bdev_alignment_offset(struct block_device *bdev) |
@@ -1147,10 +1142,8 @@ static inline int queue_discard_alignment(struct request_queue *q) | |||
1147 | return q->limits.discard_alignment; | 1142 | return q->limits.discard_alignment; |
1148 | } | 1143 | } |
1149 | 1144 | ||
1150 | static inline int queue_sector_discard_alignment(struct request_queue *q, | 1145 | static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector_t sector) |
1151 | sector_t sector) | ||
1152 | { | 1146 | { |
1153 | struct queue_limits *lim = &q->limits; | ||
1154 | unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); | 1147 | unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); |
1155 | 1148 | ||
1156 | return (lim->discard_granularity + lim->discard_alignment - alignment) | 1149 | return (lim->discard_granularity + lim->discard_alignment - alignment) |