summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2002-06-18 04:16:28 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-06-18 04:16:28 -0700
commit2dc0a8b31704495f79a83e986587e18d555e4eaf (patch)
treeac50687ba9324eeb2309a611a66366bab54ca3a5 /drivers
parent3c0c2a7b00f7dd52ee7c779e3cf86b3b1dcab777 (diff)
[PATCH] md 10 of 22 - Remove nb_dev from mddev_s
The nb_dev field is not needed. Most uses are the test if it is zero or not, and they can be replaced by tests on the emptiness of the disks list. Other uses are for iterating through devices in numerical order and it makes the code clearer (IMO) to unroll the devices into an array first (which has to be done at some stage anyway) and then walk that array. This makes ITERATE_RDEV_ORDERED un-necessary. Also remove the "name" field which is never used.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/linear.c35
-rw-r--r--drivers/md/md.c81
-rw-r--r--drivers/md/raid0.c72
3 files changed, 83 insertions, 105 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b5889b31d491..cac413d91712 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -33,39 +33,45 @@ static int linear_run (mddev_t *mddev)
linear_conf_t *conf;
struct linear_hash *table;
mdk_rdev_t *rdev;
- int size, i, j, nb_zone;
+ int size, i, nb_zone, cnt;
unsigned int curr_offset;
+ struct list_head *tmp;
MOD_INC_USE_COUNT;
conf = kmalloc (sizeof (*conf), GFP_KERNEL);
if (!conf)
goto out;
+ memset(conf, 0, sizeof(*conf));
mddev->private = conf;
- if (md_check_ordering(mddev)) {
- printk("linear: disks are not ordered, aborting!\n");
- goto out;
- }
/*
* Find the smallest device.
*/
conf->smallest = NULL;
- curr_offset = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev,j) {
+ cnt = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ int j = rdev->sb->this_disk.raid_disk;
dev_info_t *disk = conf->disks + j;
+ if (j < 0 || j > mddev->sb->raid_disks || disk->bdev) {
+ printk("linear: disk numbering problem. Aborting!\n");
+ goto out;
+ }
+
disk->dev = rdev->dev;
disk->bdev = rdev->bdev;
atomic_inc(&rdev->bdev->bd_count);
disk->size = rdev->size;
- disk->offset = curr_offset;
-
- curr_offset += disk->size;
if (!conf->smallest || (disk->size < conf->smallest->size))
conf->smallest = disk;
+ cnt++;
+ }
+ if (cnt != mddev->sb->raid_disks) {
+ printk("linear: not enough drives present. Aborting!\n");
+ goto out;
}
nb_zone = conf->nr_zones =
@@ -81,10 +87,13 @@ static int linear_run (mddev_t *mddev)
* Here we generate the linear hash table
*/
table = conf->hash_table;
- i = 0;
size = 0;
- for (j = 0; j < mddev->nb_dev; j++) {
- dev_info_t *disk = conf->disks + j;
+ curr_offset = 0;
+ for (i = 0; i < cnt; i++) {
+ dev_info_t *disk = conf->disks + i;
+
+ disk->offset = curr_offset;
+ curr_offset += disk->size;
if (size < 0) {
table[-1].dev1 = disk;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6e8a9d215593..694846304d02 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -316,69 +316,6 @@ static unsigned int zoned_raid_size(mddev_t *mddev)
return 0;
}
-/*
- * We check wether all devices are numbered from 0 to nb_dev-1. The
- * order is guaranteed even after device name changes.
- *
- * Some personalities (raid0, linear) use this. Personalities that
- * provide data have to be able to deal with loss of individual
- * disks, so they do their checking themselves.
- */
-int md_check_ordering(mddev_t *mddev)
-{
- int i, c;
- mdk_rdev_t *rdev;
- struct list_head *tmp;
-
- /*
- * First, all devices must be fully functional
- */
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty) {
- printk(KERN_ERR "md: md%d's device %s faulty, aborting.\n",
- mdidx(mddev), partition_name(rdev->dev));
- goto abort;
- }
- }
-
- c = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- c++;
- }
- if (c != mddev->nb_dev) {
- MD_BUG();
- goto abort;
- }
- if (mddev->nb_dev != mddev->sb->raid_disks) {
- printk(KERN_ERR "md: md%d, array needs %d disks, has %d, aborting.\n",
- mdidx(mddev), mddev->sb->raid_disks, mddev->nb_dev);
- goto abort;
- }
- /*
- * Now the numbering check
- */
- for (i = 0; i < mddev->nb_dev; i++) {
- c = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->desc_nr == i)
- c++;
- }
- if (!c) {
- printk(KERN_ERR "md: md%d, missing disk #%d, aborting.\n",
- mdidx(mddev), i);
- goto abort;
- }
- if (c > 1) {
- printk(KERN_ERR "md: md%d, too many disks #%d, aborting.\n",
- mdidx(mddev), i);
- goto abort;
- }
- }
- return 0;
-abort:
- return 1;
-}
-
static void remove_descriptor(mdp_disk_t *disk, mdp_super_t *sb)
{
if (disk_active(disk)) {
@@ -608,8 +545,7 @@ static void bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
list_add(&rdev->same_set, &mddev->disks);
rdev->mddev = mddev;
- mddev->nb_dev++;
- printk(KERN_INFO "md: bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
+ printk(KERN_INFO "md: bind<%s>\n", partition_name(rdev->dev));
}
static void unbind_rdev_from_array(mdk_rdev_t * rdev)
@@ -619,9 +555,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
return;
}
list_del_init(&rdev->same_set);
- rdev->mddev->nb_dev--;
- printk(KERN_INFO "md: unbind<%s,%d>\n", partition_name(rdev->dev),
- rdev->mddev->nb_dev);
+ printk(KERN_INFO "md: unbind<%s>\n", partition_name(rdev->dev));
rdev->mddev = NULL;
}
@@ -709,7 +643,7 @@ static void export_array(mddev_t *mddev)
}
kick_rdev_from_array(rdev);
}
- if (mddev->nb_dev)
+ if (!list_empty(&mddev->disks))
MD_BUG();
}
@@ -1589,7 +1523,7 @@ static int do_md_run(mddev_t * mddev)
mdk_rdev_t *rdev;
- if (!mddev->nb_dev) {
+ if (list_empty(&mddev->disks)) {
MD_BUG();
return -EINVAL;
}
@@ -1729,7 +1663,7 @@ static int restart_array(mddev_t *mddev)
/*
* Complain if it has no devices
*/
- if (!mddev->nb_dev)
+ if (list_empty(&mddev->disks))
OUT(-ENXIO);
if (mddev->pers) {
@@ -2174,7 +2108,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
MD_BUG();
return -EINVAL;
}
- if (mddev->nb_dev) {
+ if (!list_empty(&mddev->disks)) {
mdk_rdev_t *rdev0 = list_entry(mddev->disks.next,
mdk_rdev_t, same_set);
if (!uuid_equal(rdev0, rdev)) {
@@ -3111,7 +3045,7 @@ static int md_status_read_proc(char *page, char **start, off_t off,
size += rdev->size;
}
- if (mddev->nb_dev) {
+ if (!list_empty(&mddev->disks)) {
if (mddev->pers)
sz += sprintf(page + sz, "\n %d blocks",
md_size[mdidx(mddev)]);
@@ -3947,6 +3881,5 @@ EXPORT_SYMBOL(md_print_devices);
EXPORT_SYMBOL(find_rdev_nr);
EXPORT_SYMBOL(md_interrupt_thread);
EXPORT_SYMBOL(mddev_map);
-EXPORT_SYMBOL(md_check_ordering);
EXPORT_SYMBOL(get_spare);
MODULE_LICENSE("GPL");
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index d172e9681cb5..d66fd722a8df 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -28,21 +28,26 @@
static int create_strip_zones (mddev_t *mddev)
{
- int i, c, j, j1, j2;
+ int i, c, j;
unsigned long current_offset, curr_zone_offset;
raid0_conf_t *conf = mddev_to_conf(mddev);
mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev;
+ struct list_head *tmp1, *tmp2;
+ struct strip_zone *zone;
+ int cnt;
/*
* The number of 'same size groups'
*/
conf->nr_strip_zones = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev1,j1) {
+ ITERATE_RDEV(mddev,rdev1,tmp1) {
printk("raid0: looking at %s\n", partition_name(rdev1->dev));
c = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev2,j2) {
- printk("raid0: comparing %s(%ld) with %s(%ld)\n", partition_name(rdev1->dev), rdev1->size, partition_name(rdev2->dev), rdev2->size);
+ ITERATE_RDEV(mddev,rdev2,tmp2) {
+ printk("raid0: comparing %s(%ld) with %s(%ld)\n",
+ partition_name(rdev1->dev), rdev1->size,
+ partition_name(rdev2->dev), rdev2->size);
if (rdev2 == rdev1) {
printk("raid0: END\n");
break;
@@ -50,7 +55,7 @@ static int create_strip_zones (mddev_t *mddev)
if (rdev2->size == rdev1->size)
{
/*
- * Not unique, dont count it as a new
+ * Not unique, don't count it as a new
* group
*/
printk("raid0: EQUAL\n");
@@ -65,29 +70,62 @@ static int create_strip_zones (mddev_t *mddev)
printk("raid0: %d zones\n", conf->nr_strip_zones);
}
}
- printk("raid0: FINAL %d zones\n", conf->nr_strip_zones);
+ printk("raid0: FINAL %d zones\n", conf->nr_strip_zones);
conf->strip_zone = vmalloc(sizeof(struct strip_zone)*
conf->nr_strip_zones);
if (!conf->strip_zone)
return 1;
+ memset(conf->strip_zone, 0,sizeof(struct strip_zone)*
+ conf->nr_strip_zones);
+ /* The first zone must contain all devices, so here we check that
+ * there is a properly alignment of slots to devices and find them all
+ */
+ zone = &conf->strip_zone[0];
+ cnt = 0;
+ smallest = NULL;
+ ITERATE_RDEV(mddev, rdev1, tmp1) {
+ int j = rdev1->sb->this_disk.raid_disk;
+
+ if (j < 0 || j >= mddev->sb->raid_disks) {
+ printk("raid0: bad disk number %d - aborting!\n", j);
+ goto abort;
+ }
+ if (zone->dev[j]) {
+ printk("raid0: multiple devices for %d - aborting!\n", j);
+ goto abort;
+ }
+ zone->dev[j] = rdev1;
+ if (!smallest || (rdev1->size <smallest->size))
+ smallest = rdev1;
+ cnt++;
+ }
+ if (cnt != mddev->sb->raid_disks) {
+ printk("raid0: too few disks (%d of %d) - aborting!\n", cnt,
+ mddev->sb->raid_disks);
+ goto abort;
+ }
+ zone->nb_dev = cnt;
+ zone->size = smallest->size * cnt;
+ zone->zone_offset = 0;
- conf->smallest = NULL;
- current_offset = 0;
- curr_zone_offset = 0;
+ conf->smallest = zone;
+ current_offset = smallest->size;
+ curr_zone_offset = zone->size;
- for (i = 0; i < conf->nr_strip_zones; i++)
+ /* now do the other zones */
+ for (i = 1; i < conf->nr_strip_zones; i++)
{
- struct strip_zone *zone = conf->strip_zone + i;
+ zone = conf->strip_zone + i;
printk("raid0: zone %d\n", i);
zone->dev_offset = current_offset;
smallest = NULL;
c = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev,j) {
-
+ for (j=0; j<cnt; j++) {
+ rdev = conf->strip_zone[0].dev[j];
printk("raid0: checking %s ...", partition_name(rdev->dev));
if (rdev->size > current_offset)
{
@@ -117,6 +155,9 @@ static int create_strip_zones (mddev_t *mddev)
}
printk("raid0: done.\n");
return 0;
+ abort:
+ vfree(conf->strip_zone);
+ return 1;
}
static int raid0_run (mddev_t *mddev)
@@ -131,11 +172,6 @@ static int raid0_run (mddev_t *mddev)
goto out;
mddev->private = (void *)conf;
- if (md_check_ordering(mddev)) {
- printk("raid0: disks are not ordered, aborting!\n");
- goto out_free_conf;
- }
-
if (create_strip_zones (mddev))
goto out_free_conf;