X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fmd%2Fraid5.c;h=bb28fd6b44feea0ba44405df2970b16cd460b7e2;hb=54071b3808ee3dc8624d9d6f1b06c4fd5308fa3b;hp=70ffbd071b2e797be6f715dd40de19a93c6567d3;hpb=0a135ba14d71fb84c691a5386aff5049691fe6d7;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 70ffbd0..bb28fd6 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -52,6 +52,7 @@ #include #include "md.h" #include "raid5.h" +#include "raid0.h" #include "bitmap.h" /* @@ -1618,7 +1619,7 @@ static void raid5_build_block(struct stripe_head *sh, int i, int previous) static void error(mddev_t *mddev, mdk_rdev_t *rdev) { char b[BDEVNAME_SIZE]; - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; pr_debug("raid5: error called\n"); if (!test_bit(Faulty, &rdev->flags)) { @@ -4057,7 +4058,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped * As the reads complete, handle_stripe will copy the data * into the destination stripe and release that stripe. */ - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; struct stripe_head *sh; sector_t first_sector, last_sector; int raid_disks = conf->previous_raid_disks; @@ -4266,7 +4267,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped /* FIXME go_faster isn't used */ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) { - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; struct stripe_head *sh; sector_t max_sector = mddev->dev_sectors; int sync_blocks; @@ -5090,7 +5091,9 @@ static int run(mddev_t *mddev) } /* Ok, everything is just fine now */ - if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group)) + if (mddev->to_remove == &raid5_attrs_group) + mddev->to_remove = NULL; + else if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group)) printk(KERN_WARNING "raid5: failed to create sysfs attributes for %s\n", mdname(mddev)); @@ -5130,14 +5133,15 @@ abort: static int stop(mddev_t *mddev) { - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; md_unregister_thread(mddev->thread); mddev->thread = NULL; mddev->queue->backing_dev_info.congested_fn = NULL; blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ free_conf(conf); - mddev->private = &raid5_attrs_group; + mddev->private = NULL; + mddev->to_remove = &raid5_attrs_group; return 0; } @@ -5178,7 +5182,7 @@ static void printall(struct seq_file *seq, raid5_conf_t *conf) static void status(struct seq_file *seq, mddev_t *mddev) { - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; int i; seq_printf(seq, " level %d, %dk chunk, algorithm %d", mddev->level, @@ -5616,6 +5620,21 @@ static void raid5_quiesce(mddev_t *mddev, int state) } +static void *raid5_takeover_raid0(mddev_t *mddev) +{ + + mddev->new_level = 5; + mddev->new_layout = ALGORITHM_PARITY_N; + mddev->new_chunk_sectors = mddev->chunk_sectors; + mddev->raid_disks += 1; + mddev->delta_disks = 1; + /* make sure it will be not marked as dirty */ + mddev->recovery_cp = MaxSector; + + return setup_conf(mddev); +} + + static void *raid5_takeover_raid1(mddev_t *mddev) { int chunksect; @@ -5745,6 +5764,16 @@ static void *raid5_takeover(mddev_t *mddev) * raid4 - trivial - just use a raid4 layout. * raid6 - Providing it is a *_6 layout */ + if (mddev->level == 0) { + /* for raid0 takeover only one zone is supported */ + struct raid0_private_data *raid0_priv + = mddev->private; + if (raid0_priv->nr_strip_zones > 1) { + printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n"); + return ERR_PTR(-EINVAL); + } + return raid5_takeover_raid0(mddev); + } if (mddev->level == 1) return raid5_takeover_raid1(mddev);