Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tejun Heo and committed by
Jens Axboe
56bca017 fa4b9074

+6 -10
+6 -10
fs/partitions/check.c
··· 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 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 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, ", ··· 604 605 if (bdops->set_capacity && 605 606 (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) { 606 607 printk(KERN_CONT "enabling native capacity\n"); 607 - capacity = bdops->set_capacity(disk, ~0ULL); 608 + bdops->set_capacity(disk, ~0ULL); 608 609 disk->flags |= GENHD_FL_NATIVE_CAPACITY; 609 - if (capacity > get_capacity(disk)) { 610 - set_capacity(disk, capacity); 611 - check_disk_size_change(disk, bdev); 612 - bdev->bd_invalidated = 0; 613 - } 614 - goto try_scan; 610 + /* free state and restart */ 611 + kfree(state); 612 + goto rescan; 615 613 } else { 616 614 /* 617 615 * we can not ignore partitions of broken tables