diff options
author | Tejun Heo <tj@kernel.org> | 2008-08-25 06:47:22 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-09 02:56:06 -0400 |
commit | bcce3de1be61e424deef35d1e86e86a35c4b6e65 (patch) | |
tree | cfdefb52bc37c61dfac160951a9beb86d5cd9ba0 /fs/partitions | |
parent | c9959059161ddd7bf4670cf47367033d6b2f79c4 (diff) |
block: implement extended dev numbers
Implement extended device numbers. A block driver can tell block
layer that it wants to use extended device numbers. After the usual
minor space is used up, block layer automatically allocates devt's
from EXT_BLOCK_MAJOR.
Currently only one major number is allocated for this but as the
allocation is strictly on-demand, ~1mil minor space under it should
suffice unless the system actually has more than ~1mil partitions and
if that ever happens adding more majors to the extended devt area is
easy.
Due to internal implementation issues, the first partition can't be
allocated on the extended area. In other words, genhd->minors should
at least be 1. This limitation will be lifted by later changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/partitions')
-rw-r--r-- | fs/partitions/check.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index c442f0aadac3..0d4b7f28f13f 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -333,6 +333,7 @@ void delete_partition(struct gendisk *disk, int partno) | |||
333 | if (!part) | 333 | if (!part) |
334 | return; | 334 | return; |
335 | 335 | ||
336 | blk_free_devt(part_devt(part)); | ||
336 | rcu_assign_pointer(disk->__part[partno-1], NULL); | 337 | rcu_assign_pointer(disk->__part[partno-1], NULL); |
337 | kobject_put(part->holder_dir); | 338 | kobject_put(part->holder_dir); |
338 | device_del(&part->dev); | 339 | device_del(&part->dev); |
@@ -352,6 +353,7 @@ int add_partition(struct gendisk *disk, int partno, | |||
352 | sector_t start, sector_t len, int flags) | 353 | sector_t start, sector_t len, int flags) |
353 | { | 354 | { |
354 | struct hd_struct *p; | 355 | struct hd_struct *p; |
356 | dev_t devt = MKDEV(0, 0); | ||
355 | int err; | 357 | int err; |
356 | 358 | ||
357 | if (disk->__part[partno - 1]) | 359 | if (disk->__part[partno - 1]) |
@@ -378,11 +380,15 @@ int add_partition(struct gendisk *disk, int partno, | |||
378 | "%s%d", disk->dev.bus_id, partno); | 380 | "%s%d", disk->dev.bus_id, partno); |
379 | 381 | ||
380 | device_initialize(&p->dev); | 382 | device_initialize(&p->dev); |
381 | p->dev.devt = MKDEV(disk->major, disk->first_minor + partno); | ||
382 | p->dev.class = &block_class; | 383 | p->dev.class = &block_class; |
383 | p->dev.type = &part_type; | 384 | p->dev.type = &part_type; |
384 | p->dev.parent = &disk->dev; | 385 | p->dev.parent = &disk->dev; |
385 | 386 | ||
387 | err = blk_alloc_devt(p, &devt); | ||
388 | if (err) | ||
389 | goto out_put; | ||
390 | p->dev.devt = devt; | ||
391 | |||
386 | /* delay uevent until 'holders' subdir is created */ | 392 | /* delay uevent until 'holders' subdir is created */ |
387 | p->dev.uevent_suppress = 1; | 393 | p->dev.uevent_suppress = 1; |
388 | err = device_add(&p->dev); | 394 | err = device_add(&p->dev); |
@@ -419,6 +425,7 @@ out_del: | |||
419 | device_del(&p->dev); | 425 | device_del(&p->dev); |
420 | out_put: | 426 | out_put: |
421 | put_device(&p->dev); | 427 | put_device(&p->dev); |
428 | blk_free_devt(devt); | ||
422 | return err; | 429 | return err; |
423 | } | 430 | } |
424 | 431 | ||