RE: [PATCH 2/5] imsm: prepare update for level migrations reshape

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: NeilBrown [mailto:neilb@xxxxxxx]
> Sent: Tuesday, February 15, 2011 2:27 AM
> To: Kwolek, Adam
> Cc: linux-raid@xxxxxxxxxxxxxxx; Williams, Dan J; Ciechanowski, Ed;
> Neubauer, Wojciech
> Subject: Re: [PATCH 2/5] imsm: prepare update for level migrations
> reshape
> 
> On Mon, 14 Feb 2011 14:12:57 +0100 Adam Kwolek <adam.kwolek@xxxxxxxxx>
> wrote:
> 
> > For level migrations:
> > 1. raid0->raid5
> > 2. raid5->raid0
> > metadata update is prepared
> >
> > For migration raid0->raid5 spare device is required.
> > It is checked in mdadm for spares, but it is not included in to
> update.
> > Mdmon will decide what spare device
> >
> > Signed-off-by: Adam Kwolek <adam.kwolek@xxxxxxxxx>
> > ---
> >
> >  super-intel.c |  116
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 files changed, 114 insertions(+), 2 deletions(-)
> >
> > diff --git a/super-intel.c b/super-intel.c
> > index f3e248e..489340f 100644
> > --- a/super-intel.c
> > +++ b/super-intel.c
> > @@ -305,6 +305,7 @@ enum imsm_update_type {
> >  	update_rename_array,
> >  	update_add_remove_disk,
> >  	update_reshape_container_disks,
> > +	update_reshape_migration,
> >  	update_takeover
> >  };
> >
> > @@ -340,6 +341,12 @@ struct imsm_update_reshape {
> >  	enum imsm_update_type type;
> >  	int old_raid_disks;
> >  	int new_raid_disks;
> > +	/* fields for array migration changes
> > +	 */
> > +	int subdev;
> > +	int new_level;
> > +	int new_layout;
> > +
> 
> I don't like how you are overloading this structure.  You are adding
> fields
> to a structure that doesn't need them in its original context, and
> using a
> structure containing old_raid_disks and new_raid_disks in a context
> where
> they are needed.
> 
> It would be much better to have a separate structure for each different
> imsm_update_type.
> 
> 
> >  	int new_disks[1]; /* new_raid_disks - old_raid_disks makedev
> number */
> 
> Hmmm... new_disks is already there, isn't it.
> I'm not at all sure that I'm happy about that.
> It is used when increasing the number of devices in an array, but I
> would
> like that to just change  the numbers and leave mdmon to add the
> devices.
> 
> 'reshape_super'  should just verify that the change is legal, update
> the
> metadata to show that the change has happened or is happening, and
> possibly
> create an update to send to mdmon.
> reshape_super should not choose or allocate spares.
> 
> 'prepare_update' should *only* perform any allocations that
> process_update
> will need.  It doesn't allocate spares either.  It *only* allocates
> memory.
> 
> 'process_update' takes the update description and modifies the
> metadata, and
> updates internal data structures so that they accurately reflect the
> information in the metadata.  It doesn't allocate spares either.
> 
> 'activate_spare' is the only place that should activate spares.  It
> analyses
> the array, determines if any devices need to be added, finds them, and
> creates a metadata update to describe the new devices.
> manage_member() then adds them to the array and process_update
> eventually
> records these new allocations in the metadata.
> 
> It is really important to keep these function separate and make sure
> each
> function just does the one thing that it is supposed to do.  Otherwise
> all
> the interactions become too complex and so are easily broken.



I'll think how to connect all together.



> 
> 
> >  };
> >
> > @@ -6133,6 +6140,9 @@ static void imsm_process_update(struct
> supertype *st,
> >  			super->updates_pending++;
> >  		break;
> >  	}
> > +	case update_reshape_migration: {
> > +		break;
> > +	}
> >  	case update_activate_spare: {
> >  		struct imsm_update_activate_spare *u = (void *) update-
> >buf;
> >  		struct imsm_dev *dev = get_imsm_dev(super, u->array);
> > @@ -6526,6 +6536,9 @@ static void imsm_prepare_update(struct
> supertype *st,
> >  		dprintf("New anchor length is %llu\n", (unsigned long
> long)len);
> >  		break;
> >  	}
> > +	case update_reshape_migration: {
> > +		break;
> > +	}
> >  	case update_create_array: {
> >  		struct imsm_update_create_array *u = (void *) update->buf;
> >  		struct intel_dev *dv;
> > @@ -6892,6 +6905,89 @@ abort:
> >  	return 0;
> >  }
> >
> >
> +/*********************************************************************
> *********
> > + * function: imsm_create_metadata_update_for_migration()
> > + *           Creates update for IMSM array.
> > + *
> > +
> ***********************************************************************
> *******/
> > +static int imsm_create_metadata_update_for_migration(
> > +					struct supertype *st,
> > +					struct geo_params *geo,
> > +					struct imsm_update_reshape **updatep)
> > +{
> > +	struct intel_super *super = st->sb;
> > +	int update_memory_size = 0;
> > +	struct imsm_update_reshape *u = NULL;
> > +	int delta_disks = 0;
> > +	struct imsm_dev *dev;
> > +	int previous_level = -1;
> > +
> > +	dprintf("imsm_create_metadata_update_for_migration(enter)"
> > +		" New Level = %i\n", geo->level);
> > +	delta_disks = 0;
> > +
> > +	/* size of all update data without anchor */
> > +	update_memory_size = sizeof(struct imsm_update_reshape);
> > +
> > +	/* now add space for spare disks that we need to add. */
> > +	if (delta_disks > 0)
> > +		update_memory_size += sizeof(u->new_disks[0])
> > +					* (delta_disks - 1);
> > +
> > +	u = calloc(1, update_memory_size);
> > +	if (u == NULL) {
> > +		dprintf("error: cannot get memory for "
> > +			"imsm_create_metadata_update_for_migration\n");
> > +		return 0;
> > +	}
> > +	u->type = update_reshape_migration;
> > +	u->subdev = super->current_vol;
> > +	u->new_level = geo->level;
> > +	u->new_layout = geo->layout;
> > +	u->new_raid_disks = u->old_raid_disks = geo->raid_disks;
> > +	u->new_disks[0] = -1;
> > +
> > +	dev = get_imsm_dev(super, u->subdev);
> > +	if (dev) {
> > +		struct imsm_map *map;
> > +
> > +		map = get_imsm_map(dev, 0);
> > +		if (map)
> > +			previous_level = map->raid_level;
> > +	}
> > +	if ((geo->level == 5) && (previous_level == 0)) {
> > +		struct mdinfo *spares = NULL;
> > +
> > +		u->new_raid_disks++;
> > +		spares = get_spares_for_grow(st);
> 
> And here you are allocating spares in mdadm even though we agreed that
> you
> weren't going to do that.
> 
> 
> NeilBrown

Yes you are right, using spares below is my mistake during code rebasing.
Allocating spares I think is ok as spares check, but not using them.

Summarizing I have make some changes to all patches.
This have to wait few day, I'm working now on issue in expansion.
Details, I'll sent you shortly.

BR
Adam

> 
> 
> 
> 
> > +		if (spares) {
> > +			struct dl *dl;
> > +			struct mdinfo *dev;
> > +
> > +			dev = spares->devs;
> > +			if (dev) {
> > +				u->new_disks[0] = makedev(dev->disk.major,
> > +							  dev->disk.minor);
> > +				dl = get_disk_super(super,
> > +						    dev->disk.major,
> > +						    dev->disk.minor);
> > +				dl->index = u->old_raid_disks;
> > +				dev = dev->next;
> > +			}
> > +			sysfs_free(spares);
> > +		} else {
> > +			free(u);
> > +			dprintf("error: cannot get spare device "
> > +				"for requested migration");
> > +			return 0;
> > +		}
> > +	}
> > +	dprintf("imsm: reshape update preparation : OK\n");
> > +	*updatep = u;
> > +
> > +	return update_memory_size;
> > +}
> > +
> >  static void imsm_update_metadata_locally(struct supertype *st,
> >  					 void *buf, int len)
> >  {
> > @@ -7146,9 +7242,25 @@ static int imsm_reshape_super(struct supertype
> *st, long long size, int level,
> >  		case CH_TAKEOVER:
> >  			ret_val = imsm_takeover(st, &geo);
> >  			break;
> > -		case CH_MIGRATION:
> > +		case CH_MIGRATION: {
> > +			struct imsm_update_reshape *u = NULL;
> > +			int len =
> > +				imsm_create_metadata_update_for_migration(
> > +					st, &geo, &u);
> > +			if (len < 1) {
> > +				dprintf("imsm: "
> > +					"Cannot prepare update\n");
> > +			}
> >  			ret_val = 0;
> > -			break;
> > +			/* update metadata locally */
> > +			imsm_update_metadata_locally(st, u, len);
> > +			/* and possibly remotely */
> > +			if (st->update_tail)
> > +				append_metadata_update(st, u, len);
> > +			else
> > +				free(u);
> > +		}
> > +		break;
> >  		default:
> >  			ret_val = 1;
> >  		}

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux