RCS file: /usr/local/cvsroot/linux-2.6/fs/partitions/check.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 check.c --- check.c 22 Aug 2004 11:08:27 -0000 1.1.1.1 +++ check.c 22 Aug 2004 22:09:11 -0000 @@ -391,19 +391,44 @@ void register_disk(struct gendisk *disk) blkdev_put(bdev); } +/* + * Determine the last partition. + * Return the partition number or 0 if there is no partition + */ +static int get_last_partition(struct gendisk *disk) +{ + int n, ret = 0; + + for (n=0; n < disk->minors ; n++) { + if (disk->part[n]) + ret=n+1; + } + + return(ret); +} + int rescan_partitions(struct gendisk *disk, struct block_device *bdev) { struct parsed_partitions *state; + struct hd_struct *phd; int p, res; + int is_busy = 0, last_partition = 0; + + if (bdev->bd_part_count) { + is_busy = 1; + last_partition=get_last_partition(disk); + } - if (bdev->bd_part_count) - return -EBUSY; res = invalidate_partition(disk, 0); if (res) return res; bdev->bd_invalidated = 0; - for (p = 1; p < disk->minors; p++) - delete_partition(disk, p); + + if (!is_busy) { + for (p = 1; p < disk->minors; p++) + delete_partition(disk, p); + } + if (disk->fops->revalidate_disk) disk->fops->revalidate_disk(disk); if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) @@ -411,13 +436,29 @@ int rescan_partitions(struct gendisk *di for (p = 1; p < state->limit; p++) { sector_t size = state->parts[p].size; sector_t from = state->parts[p].from; + + if (is_busy && p<=last_partition) { + phd=disk->part[p-1]; + if (phd != NULL && (phd->start_sect != from || + phd->nr_sects != size)) { + printk(KERN_INFO + "Existing partition was changed. " + "Reboot is required.\n"); + res=-EBUSY; + break; + } + } + if (!size) continue; - add_partition(disk, p, from, size); + + if (!is_busy || p>last_partition) { + add_partition(disk, p, from, size); #ifdef CONFIG_BLK_DEV_MD - if (state->parts[p].flags) - md_autodetect_dev(bdev->bd_dev+p); + if (state->parts[p].flags) + md_autodetect_dev(bdev->bd_dev+p); #endif + } } kfree(state); return res;