| @@ -546,28 +546,49 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) · 545 unmodified lines |
| 546 | 546 | |
| 547 | 547 | /* add partitions */ |
| 548 | 548 | for (p = 1; p < state->limit; p++) { |
| 549 | | − sector_t size = state->parts[p].size; |
| 550 | | − sector_t from = state->parts[p].from; |
| 549 | + sector_t size, from; |
| 550 | +try_scan: |
| 551 | + size = state->parts[p].size; |
| 551 | 552 | if (!size) |
| 552 | 553 | continue; |
| 554 | + |
| 555 | + from = state->parts[p].from; |
| 553 | 556 | if (from >= get_capacity(disk)) { |
| 554 | 557 | printk(KERN_WARNING |
| 555 | 558 | "%s: p%d ignored, start %llu is behind the end of the disk\n", |
| 556 | 559 | disk->disk_name, p, (unsigned long long) from); |
| 557 | 560 | continue; |
| 558 | 561 | } |
| 562 | + |
| 559 | 563 | if (from + size > get_capacity(disk)) { |
| 560 | | − /* |
| 561 | | − * we can not ignore partitions of broken tables |
| 562 | | − * created by for example camera firmware, but we |
| 563 | | − * limit them to the end of the disk to avoid |
| 564 | | − * creating invalid block devices |
| 565 | | − */ |
| 564 | + struct block_device_operations *bdops = disk->fops; |
| 565 | + unsigned long long capacity; |
| 566 | + |
| 566 | 567 | printk(KERN_WARNING |
| 567 | | − "%s: p%d size %llu exceeds device capacity, " |
| 568 | | − "limited to end of disk\n", |
| 568 | + "%s: p%d size %llu exceeds device capacity, ", |
| 569 | 569 | disk->disk_name, p, (unsigned long long) size); |
| 570 | | − size = get_capacity(disk) - from; |
| 570 | + |
| 571 | + if (bdops->set_capacity && |
| 572 | + (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) { |
| 573 | + printk(KERN_CONT "enabling native capacity\n"); |
| 574 | + capacity = bdops->set_capacity(disk, ~0ULL); |
| 575 | + disk->flags |= GENHD_FL_NATIVE_CAPACITY; |
| 576 | + if (capacity > get_capacity(disk)) { |
| 577 | + set_capacity(disk, capacity); |
| 578 | + check_disk_size_change(disk, bdev); |
| 579 | + bdev->bd_invalidated = 0; |
| 580 | + } |
| 581 | + goto try_scan; |
| 582 | + } else { |
| 583 | + /* |
| 584 | + * we can not ignore partitions of broken tables |
| 585 | + * created by for example camera firmware, but |
| 586 | + * we limit them to the end of the disk to avoid |
| 587 | + * creating invalid block devices |
| 588 | + */ |
| 589 | + printk(KERN_CONT "limited to end of disk\n"); |
| 590 | + size = get_capacity(disk) - from; |
| 591 | + } |
| 571 | 592 | } |
| 572 | 593 | part = add_partition(disk, p, from, size, |
| 573 | 594 | state->parts[p].flags); |