summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-09-03 09:06:42 +0200
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 08:56:07 +0200
commitb5d0b9df0ba5d9a044f3a21e7544f53d90bd1465 (patch)
treed3347c1cfc59cf5d38c2c9adc2423f9d9b4cf818 /block
parented9e1982347b36573cd622ee5f4e2a7ccd79b3fd (diff)
downloadlinux-stable-b5d0b9df0ba5d9a044f3a21e7544f53d90bd1465.tar.gz
linux-stable-b5d0b9df0ba5d9a044f3a21e7544f53d90bd1465.tar.bz2
linux-stable-b5d0b9df0ba5d9a044f3a21e7544f53d90bd1465.zip
block: introduce partition 0
genhd and partition code handled disk and partitions separately. All information about the whole disk was in struct genhd and partitions in struct hd_struct. However, the whole disk (part0) and other partitions have a lot in common and the data structures end up having good number of common fields and thus separate code paths doing the same thing. Also, the partition array was indexed by partno - 1 which gets pretty confusing at times. This patch introduces partition 0 and makes the partition array indexed by partno. Following patches will unify the handling of disk and parts piece-by-piece. This patch also implements disk_partitionable() which tests whether a disk is partitionable. With coming dynamic partition array change, the most common usage of disk_max_parts() will be testing whether a disk is partitionable and the number of max partitions will become much less important. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r--block/genhd.c40
-rw-r--r--block/ioctl.c4
2 files changed, 25 insertions, 19 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 0a2f16bd54b7..65b7386c26d8 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -54,10 +54,10 @@ struct hd_struct *disk_get_part(struct gendisk *disk, int partno)
{
struct hd_struct *part;
- if (unlikely(partno < 1 || partno > disk_max_parts(disk)))
+ if (unlikely(partno < 0 || partno >= disk_max_parts(disk)))
return NULL;
rcu_read_lock();
- part = rcu_dereference(disk->__part[partno - 1]);
+ part = rcu_dereference(disk->__part[partno]);
if (part)
get_device(part_to_dev(part));
rcu_read_unlock();
@@ -85,8 +85,10 @@ void disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
if (flags & DISK_PITER_REVERSE)
piter->idx = disk_max_parts(piter->disk) - 1;
- else
+ else if (flags & DISK_PITER_INCL_PART0)
piter->idx = 0;
+ else
+ piter->idx = 1;
piter->flags = flags;
}
@@ -114,7 +116,10 @@ struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter)
/* determine iteration parameters */
if (piter->flags & DISK_PITER_REVERSE) {
inc = -1;
- end = -1;
+ if (piter->flags & DISK_PITER_INCL_PART0)
+ end = -1;
+ else
+ end = 0;
} else {
inc = 1;
end = disk_max_parts(piter->disk);
@@ -177,7 +182,7 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
{
int i;
- for (i = 0; i < disk_max_parts(disk); i++) {
+ for (i = 1; i < disk_max_parts(disk); i++) {
struct hd_struct *part = rcu_dereference(disk->__part[i]);
if (part && part->start_sect <= sector &&
@@ -669,7 +674,7 @@ static int show_partition(struct seq_file *seqf, void *v)
char buf[BDEVNAME_SIZE];
/* Don't show non-partitionable removeable devices or empty devices */
- if (!get_capacity(sgp) || (!disk_max_parts(sgp) &&
+ if (!get_capacity(sgp) || (!disk_partitionable(sgp) &&
(sgp->flags & GENHD_FL_REMOVABLE)))
return 0;
if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
@@ -742,7 +747,7 @@ static ssize_t disk_ext_range_show(struct device *dev,
{
struct gendisk *disk = dev_to_disk(dev);
- return sprintf(buf, "%d\n", disk_max_parts(disk) + 1);
+ return sprintf(buf, "%d\n", disk_max_parts(disk));
}
static ssize_t disk_removable_show(struct device *dev,
@@ -998,7 +1003,7 @@ dev_t blk_lookup_devt(const char *name, int partno)
if (strcmp(dev->bus_id, name))
continue;
- if (partno < 0 || partno > disk_max_parts(disk))
+ if (partno < 0 || partno >= disk_max_parts(disk))
continue;
if (partno == 0)
@@ -1045,21 +1050,22 @@ struct gendisk *alloc_disk_ext_node(int minors, int ext_minors, int node_id)
GFP_KERNEL | __GFP_ZERO, node_id);
if (disk) {
int tot_minors = minors + ext_minors;
+ int size = tot_minors * sizeof(struct hd_struct *);
if (!init_disk_stats(disk)) {
kfree(disk);
return NULL;
}
- if (tot_minors > 1) {
- int size = (tot_minors - 1) * sizeof(struct hd_struct *);
- disk->__part = kmalloc_node(size,
- GFP_KERNEL | __GFP_ZERO, node_id);
- if (!disk->__part) {
- free_disk_stats(disk);
- kfree(disk);
- return NULL;
- }
+
+ disk->__part = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO,
+ node_id);
+ if (!disk->__part) {
+ free_disk_stats(disk);
+ kfree(disk);
+ return NULL;
}
+ disk->__part[0] = &disk->part0;
+
disk->minors = minors;
disk->ext_minors = ext_minors;
rand_initialize_disk(disk);
diff --git a/block/ioctl.c b/block/ioctl.c
index a5f672ad55f6..64e7c67a64b0 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -30,7 +30,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
if (bdev != bdev->bd_contains)
return -EINVAL;
partno = p.pno;
- if (partno <= 0 || partno > disk_max_parts(disk))
+ if (partno <= 0 || partno >= disk_max_parts(disk))
return -EINVAL;
switch (a.op) {
case BLKPG_ADD_PARTITION:
@@ -102,7 +102,7 @@ static int blkdev_reread_part(struct block_device *bdev)
struct gendisk *disk = bdev->bd_disk;
int res;
- if (!disk_max_parts(disk) || bdev != bdev->bd_contains)
+ if (!disk_partitionable(disk) || bdev != bdev->bd_contains)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;