From mboxrd@z Thu Jan 1 00:00:00 1970 From: Neil Brown Subject: Re: [PATCH 1/3] md:Add support for Raid0->Raid5 takeover Date: Mon, 1 Feb 2010 10:58:06 +1100 Message-ID: <20100201105806.62e4dd94@notabene.brown> References: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: Sender: linux-raid-owner@vger.kernel.org To: "Trela, Maciej" Cc: "linux-raid@vger.kernel.org" , "Williams, Dan J" , "Ciechanowski, Ed" List-Id: linux-raid.ids On Fri, 29 Jan 2010 14:54:03 +0000 "Trela, Maciej" wrote: > Hello Neil, I'm sending patches with new takeover transitions proposal: > 0->5(4), 5(4)->0, 10->0, 0->10. > > Regards, > Maciek > > > Signed-off-by: Maciej Trela > --- > drivers/md/raid5.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 50 insertions(+), 0 deletions(-) > > diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c > index e84204e..0fe78ea 100644 > --- a/drivers/md/raid5.c > +++ b/drivers/md/raid5.c > @@ -5614,6 +5614,39 @@ static void raid5_quiesce(mddev_t *mddev, int state) > } > > > +static void *raid5_takeover_raid0(mddev_t *mddev) > +{ > + int chunksect; > + > + if (mddev->degraded > 0) { > + printk(KERN_ERR "ERROR: Raid0 with degraded disks!: %d\n", mddev->degraded); > + return ERR_PTR(-EINVAL); > + } > + > + chunksect = 64*2; /* 64K by default */ > + > + /* The array must be an exact multiple of chunksize */ > + while (chunksect && (mddev->array_sectors & (chunksect-1))) > + chunksect >>= 1; > + > + if ((chunksect<<9) < STRIPE_SIZE) { > + /* array size does not allow a suitable chunk size */ > + return ERR_PTR(-EINVAL); > + } This is wrong. The chunksize for RAID5 must be exactly the same as the chunksize for RAID0. There is no place for guessing. > + > + mddev->new_level = 5; > + mddev->new_layout = ALGORITHM_PARITY_N; > + mddev->new_chunk_sectors = chunksect; > + mddev->degraded++; > + mddev->raid_disks++; > + mddev->delta_disks++; > + /* 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; > @@ -5737,12 +5770,29 @@ static int raid6_check_reshape(mddev_t *mddev) > > static void *raid5_takeover(mddev_t *mddev) > { > + mdk_rdev_t *rdev; > + sector_t sectors, dev_sectors; > + > /* raid5 can take over: > * raid0 - if all devices are the same - make it a raid4 layout > * raid1 - if there are two drives. We need to know the chunk size > * raid4 - trivial - just use a raid4 layout. > * raid6 - Providing it is a *_6 layout > */ > + if (mddev->level == 0) { > + /* make sure all devices are the same (only one zone is supported) */ > + sectors = mddev->dev_sectors; > + sector_div(sectors, mddev->chunk_sectors); > + list_for_each_entry(rdev, &mddev->disks, same_set) { > + dev_sectors = rdev->sectors; > + sector_div(dev_sectors, mddev->chunk_sectors); > + if (dev_sectors != sectors) { > + printk("error: cannot takeover raid 0 with different dev sizes.\n"); > + return ERR_PTR(-EINVAL); > + } > + } > + return raid5_takeover_raid0(mddev); > + } I would rather you just look inside the raid0_private_data to see tha nr_strip_zones is zero. Thanks, NeilBrown