| @@ -546,28 +546,49 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) · 545 unmodified lines |
| 546 | | 546 | |
| 547 | /* add partitions */ | 547 | /* add partitions */ |
| 548 | for (p = 1; p < state->limit; p++) { | 548 | for (p = 1; p < state->limit; p++) { |
| 549 | sector_t size = state->parts[p].size; | 549 | sector_t size, from; |
| 550 | sector_t from = state->parts[p].from; | 550 | try_scan: |
| | 551 | size = state->parts[p].size; |
| 551 | if (!size) | 552 | if (!size) |
| 552 | continue; | 553 | continue; |
| | 554 | |
| | 555 | from = state->parts[p].from; |
| 553 | if (from >= get_capacity(disk)) { | 556 | if (from >= get_capacity(disk)) { |
| 554 | printk(KERN_WARNING | 557 | printk(KERN_WARNING |
| 555 | "%s: p%d ignored, start %llu is behind the end of the disk\n", | 558 | "%s: p%d ignored, start %llu is behind the end of the disk\n", |
| 556 | disk->disk_name, p, (unsigned long long) from); | 559 | disk->disk_name, p, (unsigned long long) from); |
| 557 | continue; | 560 | continue; |
| 558 | } | 561 | } |
| | 562 | |
| 559 | if (from + size > get_capacity(disk)) { | 563 | if (from + size > get_capacity(disk)) { |
| 560 | /* | 564 | struct block_device_operations *bdops = disk->fops; |
| 561 | * we can not ignore partitions of broken tables | 565 | unsigned long long capacity; |
| 562 | * created by for example camera firmware, but we | 566 | |
| 563 | * limit them to the end of the disk to avoid | | |
| 564 | * creating invalid block devices | | |
| 565 | */ | | |
| 566 | printk(KERN_WARNING | 567 | printk(KERN_WARNING |
| 567 | "%s: p%d size %llu exceeds device capacity, " | 568 | "%s: p%d size %llu exceeds device capacity, ", |
| 568 | "limited to end of disk\n", | | |
| 569 | disk->disk_name, p, (unsigned long long) size); | 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 | part = add_partition(disk, p, from, size, | 593 | part = add_partition(disk, p, from, size, |
| 573 | state->parts[p].flags); | 594 | state->parts[p].flags); |