Commit fe0b393f2c0a0d23a9bc9ed7dc51a1ee511098bd

Authored by Martin K. Petersen
Committed by Jens Axboe
1 parent c1152949bb

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