Commit 56bca01738733709bef076e2e97bbd01e5659f24

Authored by Tejun Heo
Committed by Jens Axboe
1 parent fa4b9074cd

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>

Showing 1 changed file with 6 additions and 10 deletions Side-by-side Diff

fs/partitions/check.c
... ... @@ -544,7 +544,7 @@
544 544 struct hd_struct *part;
545 545 struct parsed_partitions *state;
546 546 int p, highest, res;
547   -
  547 +rescan:
548 548 if (bdev->bd_part_count)
549 549 return -EBUSY;
550 550 res = invalidate_partition(disk, 0);
... ... @@ -581,7 +581,7 @@
581 581 /* add partitions */
582 582 for (p = 1; p < state->limit; p++) {
583 583 sector_t size, from;
584   -try_scan:
  584 +
585 585 size = state->parts[p].size;
586 586 if (!size)
587 587 continue;
... ... @@ -596,7 +596,6 @@
596 596  
597 597 if (from + size > get_capacity(disk)) {
598 598 const struct block_device_operations *bdops = disk->fops;
599   - unsigned long long capacity;
600 599  
601 600 printk(KERN_WARNING
602 601 "%s: p%d size %llu exceeds device capacity, ",
603 602  
... ... @@ -605,14 +604,11 @@
605 604 if (bdops->set_capacity &&
606 605 (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) {
607 606 printk(KERN_CONT "enabling native capacity\n");
608   - capacity = bdops->set_capacity(disk, ~0ULL);
  607 + bdops->set_capacity(disk, ~0ULL);
609 608 disk->flags |= GENHD_FL_NATIVE_CAPACITY;
610   - if (capacity > get_capacity(disk)) {
611   - set_capacity(disk, capacity);
612   - check_disk_size_change(disk, bdev);
613   - bdev->bd_invalidated = 0;
614   - }
615   - goto try_scan;
  609 + /* free state and restart */
  610 + kfree(state);
  611 + goto rescan;
616 612 } else {
617 613 /*
618 614 * we can not ignore partitions of broken tables