aboutsummaryrefslogtreecommitdiffstats
path: root/fs/partitions/check.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 12:29:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 12:29:42 -0400
commitd614aec4752f8c61b2e7cb77806b6bd59aa50836 (patch)
tree3b0cfb3085c43415931dbf18666d582fb8ae3c75 /fs/partitions/check.c
parentdb8e7f10ed67933ca272f4030eb7057b7f13de07 (diff)
parentad7c52d0988a8965989dc06d630c52a5bde849d5 (diff)
Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (29 commits) ide: re-implement ide_pci_init_one() on top of ide_pci_init_two() ide: unexport ide_find_dma_mode() ide: fix PowerMac bootup oops ide: skip probe if there are no devices on the port (v2) sl82c105: add printk() logging facility ide-tape: fix proc warning ide: add IDE_DFLAG_NIEN_QUIRK device flag ide: respect quirk_drives[] list on all controllers hpt366: enable all quirks for devices on quirk_drives[] list hpt366: sync quirk_drives[] list with pdc202xx_{new,old}.c ide: remove superfluous SELECT_MASK() call from do_rw_taskfile() ide: remove superfluous SELECT_MASK() call from ide_driveid_update() icside: remove superfluous ->maskproc method ide-tape: fix IDE_AFLAG_* atomic accesses ide-tape: change IDE_AFLAG_IGNORE_DSC non-atomically pdc202xx_old: kill resetproc() method pdc202xx_old: don't call pdc202xx_reset() on IRQ timeout pdc202xx_old: use ide_dma_test_irq() ide: preserve Host Protected Area by default (v2) ide-gd: implement block device ->set_capacity method (v2) ...
Diffstat (limited to 'fs/partitions/check.c')
-rw-r--r--fs/partitions/check.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 0af36085eb28..1a9c7878f864 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -556,27 +556,49 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
556 556
557 /* add partitions */ 557 /* add partitions */
558 for (p = 1; p < state->limit; p++) { 558 for (p = 1; p < state->limit; p++) {
559 sector_t size = state->parts[p].size; 559 sector_t size, from;
560 sector_t from = state->parts[p].from; 560try_scan:
561 size = state->parts[p].size;
561 if (!size) 562 if (!size)
562 continue; 563 continue;
564
565 from = state->parts[p].from;
563 if (from >= get_capacity(disk)) { 566 if (from >= get_capacity(disk)) {
564 printk(KERN_WARNING 567 printk(KERN_WARNING
565 "%s: p%d ignored, start %llu is behind the end of the disk\n", 568 "%s: p%d ignored, start %llu is behind the end of the disk\n",
566 disk->disk_name, p, (unsigned long long) from); 569 disk->disk_name, p, (unsigned long long) from);
567 continue; 570 continue;
568 } 571 }
572
569 if (from + size > get_capacity(disk)) { 573 if (from + size > get_capacity(disk)) {
570 /* 574 struct block_device_operations *bdops = disk->fops;
571 * we can not ignore partitions of broken tables 575 unsigned long long capacity;
572 * created by for example camera firmware, but we 576
573 * limit them to the end of the disk to avoid
574 * creating invalid block devices
575 */
576 printk(KERN_WARNING 577 printk(KERN_WARNING
577 "%s: p%d size %llu limited to end of disk\n", 578 "%s: p%d size %llu exceeds device capacity, ",
578 disk->disk_name, p, (unsigned long long) size); 579 disk->disk_name, p, (unsigned long long) size);
579 size = get_capacity(disk) - from; 580
581 if (bdops->set_capacity &&
582 (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) {
583 printk(KERN_CONT "enabling native capacity\n");
584 capacity = bdops->set_capacity(disk, ~0ULL);
585 disk->flags |= GENHD_FL_NATIVE_CAPACITY;
586 if (capacity > get_capacity(disk)) {
587 set_capacity(disk, capacity);
588 check_disk_size_change(disk, bdev);
589 bdev->bd_invalidated = 0;
590 }
591 goto try_scan;
592 } else {
593 /*
594 * we can not ignore partitions of broken tables
595 * created by for example camera firmware, but
596 * we limit them to the end of the disk to avoid
597 * creating invalid block devices
598 */
599 printk(KERN_CONT "limited to end of disk\n");
600 size = get_capacity(disk) - from;
601 }
580 } 602 }
581 part = add_partition(disk, p, from, size, 603 part = add_partition(disk, p, from, size,
582 state->parts[p].flags); 604 state->parts[p].flags);