svn commit: r217267 - projects/graid/head/sys/geom/raid
Alexander Motin
mav at FreeBSD.org
Tue Jan 11 17:02:25 UTC 2011
Author: mav
Date: Tue Jan 11 17:02:24 2011
New Revision: 217267
URL: http://svn.freebsd.org/changeset/base/217267
Log:
Implement method writing metadata from existing volumes/subdisks/disks.
Refactor array creation upside-down -- instead of writing metadata and
processing it, create all stuff and then run metadata writing from it.
This way seems more perspective, as we any way definitely need writing.
Modified:
projects/graid/head/sys/geom/raid/g_raid.c
projects/graid/head/sys/geom/raid/g_raid_md_if.m
projects/graid/head/sys/geom/raid/md_intel.c
Modified: projects/graid/head/sys/geom/raid/g_raid.c
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.c Tue Jan 11 14:33:10 2011 (r217266)
+++ projects/graid/head/sys/geom/raid/g_raid.c Tue Jan 11 17:02:24 2011 (r217267)
@@ -51,7 +51,7 @@ static MALLOC_DEFINE(M_RAID, "raid_data"
SYSCTL_DECL(_kern_geom);
SYSCTL_NODE(_kern_geom, OID_AUTO, raid, CTLFLAG_RW, 0, "GEOM_RAID stuff");
-u_int g_raid_debug = 1000;
+u_int g_raid_debug = 3;
TUNABLE_INT("kern.geom.raid.debug", &g_raid_debug);
SYSCTL_UINT(_kern_geom_raid, OID_AUTO, debug, CTLFLAG_RW, &g_raid_debug, 0,
"Debug level");
Modified: projects/graid/head/sys/geom/raid/g_raid_md_if.m
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid_md_if.m Tue Jan 11 14:33:10 2011 (r217266)
+++ projects/graid/head/sys/geom/raid/g_raid_md_if.m Tue Jan 11 17:02:24 2011 (r217267)
@@ -95,7 +95,6 @@ METHOD int event {
# write() - metadata write method.
METHOD int write {
struct g_raid_md_object *md;
- struct g_raid_disk *disk;
};
# free_disk() - disk destructor.
Modified: projects/graid/head/sys/geom/raid/md_intel.c
==============================================================================
--- projects/graid/head/sys/geom/raid/md_intel.c Tue Jan 11 14:33:10 2011 (r217266)
+++ projects/graid/head/sys/geom/raid/md_intel.c Tue Jan 11 17:02:24 2011 (r217267)
@@ -119,17 +119,32 @@ struct intel_raid_conf {
#define INTEL_MAGIC "Intel Raid ISM Cfg Sig. "
uint8_t version[6];
-#define INTEL_VERSION_1100 "1.1.00"
-#define INTEL_VERSION_1200 "1.2.00"
-#define INTEL_VERSION_1201 "1.2.01"
-#define INTEL_VERSION_1202 "1.2.02"
+#define INTEL_VERSION_1000 "1.0.00" /* RAID0 */
+#define INTEL_VERSION_1100 "1.1.00" /* RAID1 */
+#define INTEL_VERSION_1200 "1.2.00" /* Many volumes */
+#define INTEL_VERSION_1201 "1.2.01" /* 3 or 4 disks */
+#define INTEL_VERSION_1202 "1.2.02" /* RAID5 */
+#define INTEL_VERSION_1204 "1.2.04" /* 5 or 6 disks */
+#define INTEL_VERSION_1206 "1.2.06" /* CNG */
+#define INTEL_VERSION_1300 "1.3.00" /* Attributes */
uint8_t dummy_0[2];
uint32_t checksum;
uint32_t config_size;
uint32_t config_id;
uint32_t generation;
- uint32_t dummy_1[2];
+ uint32_t error_log_size;
+ uint32_t attributes;
+#define INTEL_ATTR_RAID0 0x00000001
+#define INTEL_ATTR_RAID1 0x00000002
+#define INTEL_ATTR_RAID10 0x00000004
+#define INTEL_ATTR_RAID1E 0x00000008
+#define INTEL_ATTR_RAID5 0x00000010
+#define INTEL_ATTR_RAIDCNG 0x00000020
+#define INTEL_ATTR_2TB 0x20000000
+#define INTEL_ATTR_PM 0x40000000
+#define INTEL_ATTR_CHECKSUM 0x80000000
+
uint8_t total_disks;
uint8_t total_volumes;
uint8_t dummy_2[2];
@@ -148,11 +163,13 @@ struct intel_raid_conf {
struct g_raid_md_intel_perdisk {
struct intel_raid_conf *pd_meta;
int pd_disk_pos;
+ struct intel_raid_disk pd_disk_meta;
};
struct g_raid_md_intel_object {
struct g_raid_md_object mdio_base;
uint32_t mdio_config_id;
+ uint32_t mdio_generation;
struct intel_raid_conf *mdio_meta;
struct callout mdio_start_co; /* STARTING state timer. */
int mdio_disks_present;
@@ -233,6 +250,7 @@ g_raid_md_intel_print(struct intel_raid_
printf("config_size 0x%08x\n", meta->config_size);
printf("config_id 0x%08x\n", meta->config_id);
printf("generation 0x%08x\n", meta->generation);
+ printf("attributes 0x%08x\n", meta->attributes);
printf("total_disks %u\n", meta->total_disks);
printf("total_volumes %u\n", meta->total_volumes);
printf("DISK# serial disk_sectors disk_id flags\n");
@@ -740,6 +758,7 @@ g_raid_md_taste_intel(struct g_raid_md_o
pd = malloc(sizeof(*pd), M_MD_INTEL, M_WAITOK | M_ZERO);
pd->pd_meta = meta;
pd->pd_disk_pos = disk_pos;
+ pd->pd_disk_meta = meta->disk[disk_pos];
disk = g_raid_create_disk(sc);
disk->d_md_data = (void *)pd;
disk->d_consumer = rcp;
@@ -782,14 +801,13 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
struct gctl_req *req)
{
struct g_raid_softc *sc;
+ struct g_raid_volume *vol;
+ struct g_raid_subdisk *sd;
struct g_raid_disk *disk;
struct g_raid_md_intel_object *mdi;
struct g_raid_md_intel_perdisk *pd;
struct g_consumer *cp;
struct g_provider *pp;
- struct intel_raid_conf *meta;
- struct intel_raid_vol *mvol;
- struct intel_raid_map *mmap;
char arg[16];
const char *verb, *volname, *levelname, *diskname;
int *nargs;
@@ -830,16 +848,7 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
return (-5);
}
numdisks = *nargs - 3;
- meta = mdi->mdio_meta = malloc(INTEL_MAX_MD_SIZE(numdisks),
- M_MD_INTEL, M_WAITOK | M_ZERO);
- memcpy(&meta->intel_id[0], INTEL_MAGIC, sizeof(INTEL_MAGIC));
- memcpy(&meta->version[0], INTEL_VERSION_1200,
- sizeof(INTEL_VERSION_1200));
- meta->config_size = INTEL_MAX_MD_SIZE(numdisks);
- meta->config_id = mdi->mdio_config_id;
- meta->generation = 1;
- meta->total_disks = numdisks;
- meta->total_volumes = 1;
+ mdi->mdio_generation = 1;
error = 0;
size = 0xffffffffffffffffllu;
sectorsize = 0;
@@ -891,7 +900,7 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
g_topology_unlock();
error = g_raid_md_get_label(cp,
- &meta->disk[i].serial[0], INTEL_SERIAL_LEN);
+ &pd->pd_disk_meta.serial[0], INTEL_SERIAL_LEN);
if (error != 0) {
gctl_error(req,
"Can't get serial for provider '%s'.",
@@ -899,31 +908,31 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
error = -8;
break;
}
- meta->disk[i].sectors = pp->mediasize / pp->sectorsize;
- if (size > meta->disk[i].sectors)
- size = meta->disk[i].sectors;
+ pd->pd_disk_meta.sectors = pp->mediasize / pp->sectorsize;
+ if (size > pp->mediasize)
+ size = pp->mediasize;
if (sectorsize < pp->sectorsize)
sectorsize = pp->sectorsize;
- meta->disk[i].id = 0xffffffff;
- meta->disk[i].flags = INTEL_F_ASSIGNED | INTEL_F_ONLINE;
+ pd->pd_disk_meta.id = 0xffffffff;
+ pd->pd_disk_meta.flags = INTEL_F_ASSIGNED | INTEL_F_ONLINE;
}
if (error != 0)
return (error);
/* Reserve some space for metadata. */
- size -= (4096 + sectorsize - 1) / sectorsize + 1;
+ size -= ((4096 + sectorsize - 1) / sectorsize) * sectorsize;
len = sizeof(*sizearg);
sizearg = gctl_get_param(req, "size", &len);
if (sizearg != NULL && len == sizeof(*sizearg)) {
- if (*sizearg / sectorsize > size) {
+ if (*sizearg > size) {
gctl_error(req, "Size too big.");
return (-9);
}
- size = *sizearg / sectorsize;
+ size = *sizearg;
}
- strip = 256;
+ strip = 131072;
len = sizeof(*striparg);
striparg = gctl_get_param(req, "strip", &len);
if (striparg != NULL && len == sizeof(*striparg)) {
@@ -935,63 +944,188 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
gctl_error(req, "Incorrect strip size.");
return (-11);
}
- strip = *striparg / sectorsize;
- if (strip >= 65536) {
+ if (strip > 65535 * sectorsize) {
gctl_error(req, "Strip size too big.");
return (-12);
}
+ strip = *striparg;
}
size -= (size % strip);
- mvol = intel_get_volume(meta, 0);
- strlcpy(&mvol->name[0], volname, sizeof(mvol->name));
+ vol = g_raid_create_volume(sc, volname);
+ vol->v_md_data = (void *)(intptr_t)0;
+ vol->v_raid_level = level;
+ vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE;
+ vol->v_strip_size = strip;
+ vol->v_disks_count = numdisks;
if (level == G_RAID_VOLUME_RL_RAID0)
- mvol->total_sectors = size * numdisks;
+ vol->v_mediasize = size * numdisks;
else if (level == G_RAID_VOLUME_RL_RAID5)
- mvol->total_sectors = size * (numdisks - 1);
+ vol->v_mediasize = size * (numdisks - 1);
else
- mvol->total_sectors = size * (numdisks / 2);
+ vol->v_mediasize = size * (numdisks / 2);
+ vol->v_sectorsize = sectorsize;
+ g_raid_start_volume(vol);
+
+ LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_intel_perdisk *)disk->d_md_data;
+ sd = &vol->v_subdisks[pd->pd_disk_pos];
+ sd->sd_disk = disk;
+ sd->sd_offset = 0;
+ sd->sd_size = size;
+ LIST_INSERT_HEAD(&disk->d_subdisks, sd, sd_next);
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_ACTIVE);
+ g_raid_event_send(sd, G_RAID_SUBDISK_E_NEW,
+ G_RAID_EVENT_SUBDISK);
+ }
+ g_raid_md_write_intel(md);
+ return (0);
+ }
+ return (-100);
+}
+
+static int
+g_raid_md_write_intel(struct g_raid_md_object *md)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_volume *vol;
+ struct g_raid_subdisk *sd;
+ struct g_raid_disk *disk;
+ struct g_raid_md_intel_object *mdi;
+ struct g_raid_md_intel_perdisk *pd;
+ struct intel_raid_conf *meta;
+ struct intel_raid_vol *mvol;
+ struct intel_raid_map *mmap;
+ off_t sectorsize = 512;
+ const char *version, *cv;
+ int i, vi, sdi, numdisks;
+
+ sc = md->mdo_softc;
+ mdi = (struct g_raid_md_intel_object *)md;
+
+ /* Count number of disks. */
+ numdisks = 0;
+ i = 0;
+ LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_intel_perdisk *)disk->d_md_data;
+ if (pd->pd_disk_meta.flags & INTEL_F_ASSIGNED) {
+ numdisks++;
+ pd->pd_disk_pos = i++;
+ }
+ }
+
+ /* Fill anchor and disks. */
+ meta = malloc(INTEL_MAX_MD_SIZE(numdisks),
+ M_MD_INTEL, M_WAITOK | M_ZERO);
+ memcpy(&meta->intel_id[0], INTEL_MAGIC, sizeof(INTEL_MAGIC));
+ memcpy(&meta->version[0], INTEL_VERSION_1200,
+ sizeof(INTEL_VERSION_1200));
+ meta->config_size = INTEL_MAX_MD_SIZE(numdisks);
+ meta->config_id = mdi->mdio_config_id;
+ meta->generation = mdi->mdio_generation;
+ meta->attributes = INTEL_ATTR_CHECKSUM;
+ meta->total_disks = numdisks;
+ LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_intel_perdisk *)disk->d_md_data;
+ if ((pd->pd_disk_meta.flags & INTEL_F_ASSIGNED) == 0)
+ continue;
+ meta->disk[pd->pd_disk_pos] = pd->pd_disk_meta;
+ }
+
+ /* Fill volumes and maps. */
+ vi = 0;
+ version = INTEL_VERSION_1000;
+ LIST_FOREACH(vol, &sc->sc_volumes, v_next) {
+ mvol = intel_get_volume(meta, vi);
mmap = intel_get_map(mvol, 0);
- mmap->offset = 0;
- mmap->disk_sectors = size;
- mmap->stripe_count = size / strip;
- mmap->stripe_sectors = strip;
+
+ for (sdi = 0; sdi < vol->v_disks_count; sdi++) {
+ sd = &vol->v_subdisks[sdi];
+ if (sd->sd_disk != NULL)
+ break;
+ }
+ if (sdi >= vol->v_disks_count)
+ panic("No any filled subdisk in volume");
+ if (vol->v_mediasize >= 0x20000000000llu)
+ meta->attributes |= INTEL_ATTR_2TB;
+ if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID0)
+ meta->attributes |= INTEL_ATTR_RAID0;
+ else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1)
+ meta->attributes |= INTEL_ATTR_RAID1;
+ else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID5)
+ meta->attributes |= INTEL_ATTR_RAID5;
+ else
+ meta->attributes |= INTEL_ATTR_RAID10;
+
+ if (meta->attributes & INTEL_ATTR_2TB)
+ cv = INTEL_VERSION_1300;
+// else if (dev->status == DEV_CLONE_N_GO)
+// cv = INTEL_VERSION_1206;
+ else if (vol->v_disks_count > 4)
+ cv = INTEL_VERSION_1204;
+ else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID5)
+ cv = INTEL_VERSION_1202;
+ else if (vol->v_disks_count > 2)
+ cv = INTEL_VERSION_1201;
+ else if (vi > 0)
+ cv = INTEL_VERSION_1200;
+ else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1)
+ cv = INTEL_VERSION_1100;
+ else
+ cv = INTEL_VERSION_1000;
+ if (strcmp(cv, version) > 0)
+ version = cv;
+
+ strlcpy(&mvol->name[0], vol->v_name, sizeof(mvol->name));
+ mvol->total_sectors = vol->v_mediasize / sectorsize;
+ mmap->offset = sd->sd_offset / sectorsize;
+ mmap->disk_sectors = sd->sd_size / sectorsize;
+ mmap->stripe_count = sd->sd_size / vol->v_strip_size;
+ mmap->stripe_sectors = vol->v_strip_size / sectorsize;
mmap->status = INTEL_S_READY;
- if (level == G_RAID_VOLUME_RL_RAID0)
+ if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID0)
mmap->type = INTEL_T_RAID0;
- else if (level == G_RAID_VOLUME_RL_RAID1 ||
- level == G_RAID_VOLUME_RL_RAID10)
+ else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1 ||
+ vol->v_raid_level == G_RAID_VOLUME_RL_RAID10)
mmap->type = INTEL_T_RAID1;
else
mmap->type = INTEL_T_RAID5;
- mmap->total_disks = numdisks;
- if (level == G_RAID_VOLUME_RL_RAID10)
- mmap->total_domains = numdisks / 2;
- else if (level == G_RAID_VOLUME_RL_RAID1)
- mmap->total_domains = numdisks;
+ mmap->total_disks = vol->v_disks_count;
+ if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID10)
+ mmap->total_domains = vol->v_disks_count / 2;
+ else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1)
+ mmap->total_domains = vol->v_disks_count;
else
mmap->total_domains = 1;
mmap->failed_disk_num = ~0;
mmap->ddf = 1;
- for (i = 0; i < numdisks; i++)
- mmap->disk_idx[i] = i;
- g_raid_md_intel_print(meta);
- LIST_FOREACH(disk, &sc->sc_disks, d_next) {
- pd = (struct g_raid_md_intel_perdisk *)disk->d_md_data;
- pd->pd_meta = intel_meta_copy(meta);
- intel_meta_write(disk->d_consumer, meta);
+ for (sdi = 0; sdi < vol->v_disks_count; sdi++) {
+ sd = &vol->v_subdisks[sdi];
+ pd = (struct g_raid_md_intel_perdisk *)
+ sd->sd_disk->d_md_data;
+ mmap->disk_idx[sdi] = pd->pd_disk_pos;
}
- g_raid_md_intel_start(sc);
- return (0);
+ vi++;
}
- return (-100);
-}
-
-static int
-g_raid_md_write_intel(struct g_raid_md_object *md,
- struct g_raid_disk *disk)
-{
+ meta->total_volumes = vi;
+ if (strcmp(version, INTEL_VERSION_1300) != 0)
+ meta->attributes &= INTEL_ATTR_CHECKSUM;
+ memcpy(&meta->version[0], version, sizeof(INTEL_VERSION_1000));
+ /* We are done. Print meta data and store them to disks. */
+ g_raid_md_intel_print(meta);
+ if (mdi->mdio_meta != NULL)
+ free(mdi->mdio_meta, M_MD_INTEL);
+ mdi->mdio_meta = meta;
+ LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+ pd = (struct g_raid_md_intel_perdisk *)disk->d_md_data;
+ if (pd->pd_meta != NULL) {
+ free(pd->pd_meta, M_MD_INTEL);
+ pd->pd_meta = NULL;
+ }
+ pd->pd_meta = intel_meta_copy(meta);
+ intel_meta_write(disk->d_consumer, meta);
+ }
return (0);
}
More information about the svn-src-projects
mailing list