diff options
| -rw-r--r-- | drivers/md/linear.c | 35 | ||||
| -rw-r--r-- | drivers/md/md.c | 81 | ||||
| -rw-r--r-- | drivers/md/raid0.c | 72 | ||||
| -rw-r--r-- | include/linux/raid/md.h | 1 | ||||
| -rw-r--r-- | include/linux/raid/md_k.h | 9 |
5 files changed, 83 insertions, 115 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; diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index cb6332482af2..c5516ee0c732 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -82,7 +82,6 @@ extern int md_do_sync(mddev_t *mddev, mdp_disk_t *spare); extern void md_done_sync(mddev_t *mddev, int blocks, int ok); extern void md_sync_acct(kdev_t dev, unsigned long nr_sectors); extern void md_recover_arrays (void); -extern int md_check_ordering (mddev_t *mddev); extern int md_notify_reboot(struct notifier_block *this, unsigned long code, void *x); extern int md_error (mddev_t *mddev, struct block_device *bdev); diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 5734a0275ee7..69466cd714e7 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -196,14 +196,12 @@ struct mddev_s mdk_personality_t *pers; int __minor; mdp_super_t *sb; - int nb_dev; struct list_head disks; int sb_dirty; int ro; unsigned long curr_resync; /* blocks scheduled */ unsigned long resync_mark; /* a recent timestamp */ unsigned long resync_mark_cnt;/* blocks written at resync_mark */ - char *name; int recovery_running; struct semaphore reconfig_sem; struct semaphore recovery_sem; @@ -280,13 +278,6 @@ extern mdp_disk_t *get_spare(mddev_t *mddev); #define ITERATE_RDEV(mddev,rdev,tmp) \ ITERATE_RDEV_GENERIC((mddev)->disks,same_set,rdev,tmp) -/* - * Same as above, but assumes that the device has rdev->desc_nr numbered - * from 0 to mddev->nb_dev, and iterates through rdevs in ascending order. - */ -#define ITERATE_RDEV_ORDERED(mddev,rdev,i) \ - for (i = 0; rdev = find_rdev_nr(mddev, i), i < mddev->nb_dev; i++) - /* * Iterates through all 'RAID managed disks' |
