aboutsummaryrefslogtreecommitdiffstats
path: root/fs/partitions/check.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-05-15 14:09:28 -0400
committerJens Axboe <jens.axboe@oracle.com>2010-05-21 14:01:02 -0400
commit56bca01738733709bef076e2e97bbd01e5659f24 (patch)
treed4444fe75c7571a0fd9dd24df0ae7017b26cb7c5 /fs/partitions/check.c
parentfa4b9074cd8428958c2adf9dc0c831f46e27c193 (diff)
block: restart partition scan after resizing a device
Device resize via ->set_capacity() can reveal new partitions (e.g. in chained partition table formats such as dos extended parts). Restart partition scan from the beginning after resizing a device. This change also makes libata always revalidate the disk after resize which makes lower layer native capacity unlocking implementation simpler and more robust as resize can be handled in the usual path. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Ben Hutchings <ben@decadent.org.uk> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/partitions/check.c')
-rw-r--r--fs/partitions/check.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index e238ab23a9e7..8f01df354f04 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -544,7 +544,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
544 struct hd_struct *part; 544 struct hd_struct *part;
545 struct parsed_partitions *state; 545 struct parsed_partitions *state;
546 int p, highest, res; 546 int p, highest, res;
547 547rescan:
548 if (bdev->bd_part_count) 548 if (bdev->bd_part_count)
549 return -EBUSY; 549 return -EBUSY;
550 res = invalidate_partition(disk, 0); 550 res = invalidate_partition(disk, 0);
@@ -581,7 +581,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
581 /* add partitions */ 581 /* add partitions */
582 for (p = 1; p < state->limit; p++) { 582 for (p = 1; p < state->limit; p++) {
583 sector_t size, from; 583 sector_t size, from;
584try_scan: 584
585 size = state->parts[p].size; 585 size = state->parts[p].size;
586 if (!size) 586 if (!size)
587 continue; 587 continue;
@@ -596,7 +596,6 @@ try_scan:
596 596
597 if (from + size > get_capacity(disk)) { 597 if (from + size > get_capacity(disk)) {
598 const struct block_device_operations *bdops = disk->fops; 598 const struct block_device_operations *bdops = disk->fops;
599 unsigned long long capacity;
600 599
601 printk(KERN_WARNING 600 printk(KERN_WARNING
602 "%s: p%d size %llu exceeds device capacity, ", 601 "%s: p%d size %llu exceeds device capacity, ",
@@ -605,14 +604,11 @@ try_scan:
605 if (bdops->set_capacity && 604 if (bdops->set_capacity &&
606 (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) { 605 (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) {
607 printk(KERN_CONT "enabling native capacity\n"); 606 printk(KERN_CONT "enabling native capacity\n");
608 capacity = bdops->set_capacity(disk, ~0ULL); 607 bdops->set_capacity(disk, ~0ULL);
609 disk->flags |= GENHD_FL_NATIVE_CAPACITY; 608 disk->flags |= GENHD_FL_NATIVE_CAPACITY;
610 if (capacity > get_capacity(disk)) { 609 /* free state and restart */
611 set_capacity(disk, capacity); 610 kfree(state);
612 check_disk_size_change(disk, bdev); 611 goto rescan;
613 bdev->bd_invalidated = 0;
614 }
615 goto try_scan;
616 } else { 612 } else {
617 /* 613 /*
618 * we can not ignore partitions of broken tables 614 * we can not ignore partitions of broken tables