aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-08-25 06:56:15 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:08 -0400
commit540eed5637b766bb1e881ef744c42617760b4815 (patch)
tree8bdf54967a8290f780216f767291623e67ee7e9b /fs
parent074a7aca7afa6f230104e8e65eba3420263714a5 (diff)
block: make partition array dynamic
disk->__part used to be statically allocated to the maximum possible number of partitions. This patch makes partition array allocation dynamic. The added overhead is minimal as only real change is one memory dereference changed to RCU one. This saves both a bit of memory and cpu cycles iterating through unoccupied slots and makes increasing partition limit easier. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/partitions/check.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index f517869e8d10..772b2ed8d239 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -312,14 +312,18 @@ static void delete_partition_rcu_cb(struct rcu_head *head)
312 312
313void delete_partition(struct gendisk *disk, int partno) 313void delete_partition(struct gendisk *disk, int partno)
314{ 314{
315 struct disk_part_tbl *ptbl = disk->part_tbl;
315 struct hd_struct *part; 316 struct hd_struct *part;
316 317
317 part = disk->__part[partno]; 318 if (partno >= ptbl->len)
319 return;
320
321 part = ptbl->part[partno];
318 if (!part) 322 if (!part)
319 return; 323 return;
320 324
321 blk_free_devt(part_devt(part)); 325 blk_free_devt(part_devt(part));
322 rcu_assign_pointer(disk->__part[partno], NULL); 326 rcu_assign_pointer(ptbl->part[partno], NULL);
323 kobject_put(part->holder_dir); 327 kobject_put(part->holder_dir);
324 device_del(part_to_dev(part)); 328 device_del(part_to_dev(part));
325 329
@@ -341,10 +345,16 @@ int add_partition(struct gendisk *disk, int partno,
341 dev_t devt = MKDEV(0, 0); 345 dev_t devt = MKDEV(0, 0);
342 struct device *ddev = disk_to_dev(disk); 346 struct device *ddev = disk_to_dev(disk);
343 struct device *pdev; 347 struct device *pdev;
348 struct disk_part_tbl *ptbl;
344 const char *dname; 349 const char *dname;
345 int err; 350 int err;
346 351
347 if (disk->__part[partno]) 352 err = disk_expand_part_tbl(disk, partno);
353 if (err)
354 return err;
355 ptbl = disk->part_tbl;
356
357 if (ptbl->part[partno])
348 return -EBUSY; 358 return -EBUSY;
349 359
350 p = kzalloc(sizeof(*p), GFP_KERNEL); 360 p = kzalloc(sizeof(*p), GFP_KERNEL);
@@ -398,7 +408,7 @@ int add_partition(struct gendisk *disk, int partno,
398 408
399 /* everything is up and running, commence */ 409 /* everything is up and running, commence */
400 INIT_RCU_HEAD(&p->rcu_head); 410 INIT_RCU_HEAD(&p->rcu_head);
401 rcu_assign_pointer(disk->__part[partno], p); 411 rcu_assign_pointer(ptbl->part[partno], p);
402 412
403 /* suppress uevent if the disk supresses it */ 413 /* suppress uevent if the disk supresses it */
404 if (!ddev->uevent_suppress) 414 if (!ddev->uevent_suppress)
@@ -487,7 +497,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
487 struct disk_part_iter piter; 497 struct disk_part_iter piter;
488 struct hd_struct *part; 498 struct hd_struct *part;
489 struct parsed_partitions *state; 499 struct parsed_partitions *state;
490 int p, res; 500 int p, highest, res;
491 501
492 if (bdev->bd_part_count) 502 if (bdev->bd_part_count)
493 return -EBUSY; 503 return -EBUSY;
@@ -511,6 +521,17 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
511 /* tell userspace that the media / partition table may have changed */ 521 /* tell userspace that the media / partition table may have changed */
512 kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); 522 kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
513 523
524 /* Detect the highest partition number and preallocate
525 * disk->part_tbl. This is an optimization and not strictly
526 * necessary.
527 */
528 for (p = 1, highest = 0; p < state->limit; p++)
529 if (state->parts[p].size)
530 highest = p;
531
532 disk_expand_part_tbl(disk, highest);
533
534 /* add partitions */
514 for (p = 1; p < state->limit; p++) { 535 for (p = 1; p < state->limit; p++) {
515 sector_t size = state->parts[p].size; 536 sector_t size = state->parts[p].size;
516 sector_t from = state->parts[p].from; 537 sector_t from = state->parts[p].from;