diff -urpN -X /home/fletch/.diff.exclude 600-32bit_dev_t/drivers/block/cciss.c 610-dynamic_hd_struct/drivers/block/cciss.c --- 600-32bit_dev_t/drivers/block/cciss.c Tue Apr 8 14:38:16 2003 +++ 610-dynamic_hd_struct/drivers/block/cciss.c Sun Apr 20 22:23:18 2003 @@ -599,9 +599,12 @@ static int cciss_ioctl(struct inode *ino luninfo.num_opens = drv->usage_count; luninfo.num_parts = 0; /* count partitions 1 to 15 with sizes > 0 */ - for(i=1; i part[i].nr_sects != 0) - luninfo.num_parts++; + for(i=1; i part[i]) + continue; + if (disk->part[i]->nr_sects != 0) + luninfo.num_parts++; + } if (copy_to_user((void *) arg, &luninfo, sizeof(LogvolInfo_struct))) return -EFAULT; diff -urpN -X /home/fletch/.diff.exclude 600-32bit_dev_t/drivers/block/genhd.c 610-dynamic_hd_struct/drivers/block/genhd.c --- 600-32bit_dev_t/drivers/block/genhd.c Sun Apr 20 22:18:51 2003 +++ 610-dynamic_hd_struct/drivers/block/genhd.c Sun Apr 20 22:23:18 2003 @@ -365,11 +365,13 @@ static int show_partition(struct seq_fil (unsigned long long)get_capacity(sgp) >> 1, disk_name(sgp, 0, buf)); for (n = 0; n < sgp->minors - 1; n++) { - if (sgp->part[n].nr_sects == 0) + if (!sgp->part[n]) + continue; + if (sgp->part[n]->nr_sects == 0) continue; seq_printf(part, "%4d %4d %10llu %s\n", sgp->major, n + 1 + sgp->first_minor, - (unsigned long long)sgp->part[n].nr_sects >> 1 , + (unsigned long long)sgp->part[n]->nr_sects >> 1 , disk_name(sgp, n + 1, buf)); } @@ -607,13 +609,15 @@ static int diskstats_show(struct seq_fil /* now show all non-0 size partitions of it */ for (n = 0; n < gp->minors - 1; n++) { - if (gp->part[n].nr_sects) { - struct hd_struct *hd = &gp->part[n]; - seq_printf(s, "%4d %4d %s %u %u %u %u\n", - gp->major, n + gp->first_minor + 1, - disk_name(gp, n + 1, buf), - hd->reads, hd->read_sectors, - hd->writes, hd->write_sectors); + if (gp->part[n]->nr_sects) { + struct hd_struct *hd = gp->part[n]; + + if (hd && hd->nr_sects) + seq_printf(s, "%4d %4d %s %u %u %u %u\n", + gp->major, n + gp->first_minor + 1, + disk_name(gp, n + 1, buf), + hd->reads, hd->read_sectors, + hd->writes, hd->write_sectors); } } @@ -638,7 +642,7 @@ struct gendisk *alloc_disk(int minors) return NULL; } if (minors > 1) { - int size = (minors - 1) * sizeof(struct hd_struct); + int size = (minors - 1) * sizeof(struct hd_struct *); disk->part = kmalloc(size, GFP_KERNEL); if (!disk->part) { kfree(disk); @@ -690,8 +694,8 @@ void set_device_ro(struct block_device * struct gendisk *disk = bdev->bd_disk; if (bdev->bd_contains != bdev) { int part = bdev->bd_dev - MKDEV(disk->major, disk->first_minor); - struct hd_struct *p = &disk->part[part-1]; - p->policy = flag; + struct hd_struct *p = disk->part[part-1]; + if (p) p->policy = flag; } else disk->policy = flag; } @@ -701,7 +705,7 @@ void set_disk_ro(struct gendisk *disk, i int i; disk->policy = flag; for (i = 0; i < disk->minors - 1; i++) - disk->part[i].policy = flag; + if (disk->part[i]) disk->part[i]->policy = flag; } int bdev_read_only(struct block_device *bdev) @@ -712,8 +716,9 @@ int bdev_read_only(struct block_device * disk = bdev->bd_disk; if (bdev->bd_contains != bdev) { int part = bdev->bd_dev - MKDEV(disk->major, disk->first_minor); - struct hd_struct *p = &disk->part[part-1]; - return p->policy; + struct hd_struct *p = disk->part[part-1]; + if (p) return p->policy; + return 0; } else return disk->policy; } diff -urpN -X /home/fletch/.diff.exclude 600-32bit_dev_t/drivers/block/ioctl.c 610-dynamic_hd_struct/drivers/block/ioctl.c --- 600-32bit_dev_t/drivers/block/ioctl.c Tue Jan 14 10:06:15 2003 +++ 610-dynamic_hd_struct/drivers/block/ioctl.c Sun Apr 20 22:23:18 2003 @@ -41,11 +41,14 @@ static int blkpg_ioctl(struct block_devi return -EINVAL; } /* partition number in use? */ - if (disk->part[part - 1].nr_sects != 0) + if (disk->part[part - 1]) return -EBUSY; /* overlap? */ for (i = 0; i < disk->minors - 1; i++) { - struct hd_struct *s = &disk->part[i]; + struct hd_struct *s = disk->part[i]; + + if (!s) + continue; if (!(start+length <= s->start_sect || start >= s->start_sect + s->nr_sects)) return -EBUSY; @@ -54,7 +57,9 @@ static int blkpg_ioctl(struct block_devi add_partition(disk, part, start, length); return 0; case BLKPG_DEL_PARTITION: - if (disk->part[part - 1].nr_sects == 0) + if (!disk->part[part-1]) + return -ENXIO; + if (disk->part[part - 1]->nr_sects == 0) return -ENXIO; /* partition in use? Incomplete check for now. */ bdevp = bdget(MKDEV(disk->major, disk->first_minor) + part); diff -urpN -X /home/fletch/.diff.exclude 600-32bit_dev_t/drivers/block/ll_rw_blk.c 610-dynamic_hd_struct/drivers/block/ll_rw_blk.c --- 600-32bit_dev_t/drivers/block/ll_rw_blk.c Tue Apr 8 14:38:16 2003 +++ 610-dynamic_hd_struct/drivers/block/ll_rw_blk.c Sun Apr 20 22:23:18 2003 @@ -1841,7 +1841,7 @@ static inline void blk_partition_remap(s if (bdev == bdev->bd_contains) return; - p = &disk->part[bdev->bd_dev-MKDEV(disk->major,disk->first_minor)-1]; + p = disk->part[bdev->bd_dev-MKDEV(disk->major,disk->first_minor)-1]; switch (bio->bi_rw) { case READ: p->read_sectors += bio_sectors(bio); diff -urpN -X /home/fletch/.diff.exclude 600-32bit_dev_t/fs/block_dev.c 610-dynamic_hd_struct/fs/block_dev.c --- 600-32bit_dev_t/fs/block_dev.c Tue Apr 8 14:38:19 2003 +++ 610-dynamic_hd_struct/fs/block_dev.c Sun Apr 20 22:23:18 2003 @@ -559,10 +559,10 @@ static int do_open(struct block_device * bdev->bd_contains = whole; down(&whole->bd_sem); whole->bd_part_count++; - p = disk->part + part - 1; + p = disk->part[part - 1]; bdev->bd_inode->i_data.backing_dev_info = whole->bd_inode->i_data.backing_dev_info; - if (!(disk->flags & GENHD_FL_UP) || !p->nr_sects) { + if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) { whole->bd_part_count--; up(&whole->bd_sem); ret = -ENXIO; diff -urpN -X /home/fletch/.diff.exclude 600-32bit_dev_t/fs/partitions/check.c 610-dynamic_hd_struct/fs/partitions/check.c --- 600-32bit_dev_t/fs/partitions/check.c Sun Apr 20 19:35:04 2003 +++ 610-dynamic_hd_struct/fs/partitions/check.c Sun Apr 20 22:24:49 2003 @@ -182,7 +182,7 @@ static struct sysfs_ops part_sysfs_ops = static ssize_t part_dev_read(struct hd_struct * p, char *page) { struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); - int part = p - disk->part + 1; + int part = p->partno; dev_t base = MKDEV(disk->major, disk->first_minor); return sprintf(page, "%04x\n", (unsigned)(base + part)); } @@ -234,7 +234,9 @@ struct kobj_type ktype_part = { void delete_partition(struct gendisk *disk, int part) { - struct hd_struct *p = disk->part + part - 1; + struct hd_struct *p = disk->part[part-1]; + if (!p) + return; if (!p->nr_sects) return; p->start_sect = 0; @@ -242,12 +244,19 @@ void delete_partition(struct gendisk *di p->reads = p->writes = p->read_sectors = p->write_sectors = 0; devfs_remove("%s/part%d", disk->devfs_name, part); kobject_unregister(&p->kobj); + disk->part[part-1] = NULL; + kfree(p); } void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) { - struct hd_struct *p = disk->part + part - 1; + struct hd_struct *p; + p = kmalloc(sizeof(struct hd_struct), GFP_KERNEL); + if (!p) + return; + + memset(p, 0, sizeof(struct hd_struct)); p->start_sect = start; p->nr_sects = len; devfs_register_partition(disk, part); @@ -255,6 +264,9 @@ void add_partition(struct gendisk *disk, p->kobj.parent = &disk->kobj; p->kobj.ktype = &ktype_part; kobject_register(&p->kobj); + + p->partno = part; + disk->part[part-1] = p; } static void disk_sysfs_symlinks(struct gendisk *disk) diff -urpN -X /home/fletch/.diff.exclude 600-32bit_dev_t/include/linux/genhd.h 610-dynamic_hd_struct/include/linux/genhd.h --- 600-32bit_dev_t/include/linux/genhd.h Sun Apr 20 19:35:07 2003 +++ 610-dynamic_hd_struct/include/linux/genhd.h Sun Apr 20 22:23:18 2003 @@ -64,7 +64,7 @@ struct hd_struct { sector_t nr_sects; struct kobject kobj; unsigned reads, read_sectors, writes, write_sectors; - int policy; + int policy, partno; }; #define GENHD_FL_REMOVABLE 1 @@ -89,7 +89,7 @@ struct gendisk { int minor_shift; /* number of times minor is shifted to get real minor */ char disk_name[16]; /* name of major driver */ - struct hd_struct *part; /* [indexed by minor] */ + struct hd_struct **part; /* [indexed by minor] */ struct block_device_operations *fops; struct request_queue *queue; void *private_data;