Commit fe0b393f2c0a0d23a9bc9ed7dc51a1ee511098bd
Committed by
Jens Axboe
1 parent
c1152949bb
Exists in
master
and in
39 other branches
block: Correct handling of bottom device misaligment
The top device misalignment flag would not be set if the added bottom device was already misaligned as opposed to causing a stacking failure. Also massage the reporting so that an error is only returned if adding the bottom device caused the misalignment. I.e. don't return an error if the top is already flagged as misaligned. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Showing 1 changed file with 13 additions and 4 deletions Side-by-side Diff
block/blk-settings.c
... | ... | @@ -528,7 +528,7 @@ |
528 | 528 | sector_t offset) |
529 | 529 | { |
530 | 530 | sector_t alignment; |
531 | - unsigned int top, bottom; | |
531 | + unsigned int top, bottom, ret = 0; | |
532 | 532 | |
533 | 533 | t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); |
534 | 534 | t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); |
... | ... | @@ -546,6 +546,8 @@ |
546 | 546 | t->max_segment_size = min_not_zero(t->max_segment_size, |
547 | 547 | b->max_segment_size); |
548 | 548 | |
549 | + t->misaligned |= b->misaligned; | |
550 | + | |
549 | 551 | alignment = queue_limit_alignment_offset(b, offset); |
550 | 552 | |
551 | 553 | /* Bottom device has different alignment. Check that it is |
552 | 554 | |
... | ... | @@ -558,8 +560,10 @@ |
558 | 560 | bottom = max(b->physical_block_size, b->io_min) + alignment; |
559 | 561 | |
560 | 562 | /* Verify that top and bottom intervals line up */ |
561 | - if (max(top, bottom) & (min(top, bottom) - 1)) | |
563 | + if (max(top, bottom) & (min(top, bottom) - 1)) { | |
562 | 564 | t->misaligned = 1; |
565 | + ret = -1; | |
566 | + } | |
563 | 567 | } |
564 | 568 | |
565 | 569 | t->logical_block_size = max(t->logical_block_size, |
566 | 570 | |
567 | 571 | |
... | ... | @@ -578,18 +582,21 @@ |
578 | 582 | if (t->physical_block_size & (t->logical_block_size - 1)) { |
579 | 583 | t->physical_block_size = t->logical_block_size; |
580 | 584 | t->misaligned = 1; |
585 | + ret = -1; | |
581 | 586 | } |
582 | 587 | |
583 | 588 | /* Minimum I/O a multiple of the physical block size? */ |
584 | 589 | if (t->io_min & (t->physical_block_size - 1)) { |
585 | 590 | t->io_min = t->physical_block_size; |
586 | 591 | t->misaligned = 1; |
592 | + ret = -1; | |
587 | 593 | } |
588 | 594 | |
589 | 595 | /* Optimal I/O a multiple of the physical block size? */ |
590 | 596 | if (t->io_opt & (t->physical_block_size - 1)) { |
591 | 597 | t->io_opt = 0; |
592 | 598 | t->misaligned = 1; |
599 | + ret = -1; | |
593 | 600 | } |
594 | 601 | |
595 | 602 | /* Find lowest common alignment_offset */ |
596 | 603 | |
... | ... | @@ -597,8 +604,10 @@ |
597 | 604 | & (max(t->physical_block_size, t->io_min) - 1); |
598 | 605 | |
599 | 606 | /* Verify that new alignment_offset is on a logical block boundary */ |
600 | - if (t->alignment_offset & (t->logical_block_size - 1)) | |
607 | + if (t->alignment_offset & (t->logical_block_size - 1)) { | |
601 | 608 | t->misaligned = 1; |
609 | + ret = -1; | |
610 | + } | |
602 | 611 | |
603 | 612 | /* Discard alignment and granularity */ |
604 | 613 | if (b->discard_granularity) { |
... | ... | @@ -626,7 +635,7 @@ |
626 | 635 | (t->discard_granularity - 1); |
627 | 636 | } |
628 | 637 | |
629 | - return t->misaligned ? -1 : 0; | |
638 | + return ret; | |
630 | 639 | } |
631 | 640 | EXPORT_SYMBOL(blk_stack_limits); |
632 | 641 |