svn commit: r219881 - projects/graid/head/sys/geom/raid

Alexander Motin mav at FreeBSD.org
Tue Mar 22 20:00:27 UTC 2011


Author: mav
Date: Tue Mar 22 20:00:27 2011
New Revision: 219881
URL: http://svn.freebsd.org/changeset/base/219881

Log:
  Add basic NVidia metadata write support.

Modified:
  projects/graid/head/sys/geom/raid/md_nvidia.c

Modified: projects/graid/head/sys/geom/raid/md_nvidia.c
==============================================================================
--- projects/graid/head/sys/geom/raid/md_nvidia.c	Tue Mar 22 19:52:29 2011	(r219880)
+++ projects/graid/head/sys/geom/raid/md_nvidia.c	Tue Mar 22 20:00:27 2011	(r219881)
@@ -57,37 +57,43 @@ struct nvidia_raid_conf {
 	uint32_t	sector_size;
 	uint8_t		name[16];
 	uint8_t		revision[4];
-	uint32_t	dummy_1;
+	uint32_t	disk_status;
 
 	uint32_t	magic_0;
-#define NVIDIA_MAGIC0               0x00640044
+#define NVIDIA_MAGIC0		0x00640044
 
 	uint64_t	volume_id[2];
-	uint8_t		flags;
+	uint8_t		state;
+#define NVIDIA_S_IDLE		0
+#define NVIDIA_S_INIT		2
+#define NVIDIA_S_REBUILD	3
+#define NVIDIA_S_UPGRADE	4
+#define NVIDIA_S_SYNC		5
 	uint8_t		array_width;
 	uint8_t		total_disks;
-	uint8_t		dummy_2;
+	uint8_t		orig_array_width;
 	uint16_t	type;
-#define NVIDIA_T_RAID0              0x00000080
-#define NVIDIA_T_RAID1              0x00000081
-#define NVIDIA_T_RAID3              0x00000083
-#define NVIDIA_T_RAID5              0x00000085
-#define NVIDIA_T_RAID10             0x00008180
-#define NVIDIA_T_CONCAT             0x000000ff
+#define NVIDIA_T_RAID0		0x0080
+#define NVIDIA_T_RAID1		0x0081
+#define NVIDIA_T_RAID3		0x0083
+#define NVIDIA_T_RAID5		0x0085	/* RLQ = 00/02? */
+#define NVIDIA_T_RAID5_SYM	0x0095	/* RLQ = 03 */
+#define NVIDIA_T_RAID10		0x8180
+#define NVIDIA_T_CONCAT		0x00ff
 
 	uint16_t	dummy_3;
 	uint32_t	strip_sectors;
 	uint32_t	strip_bytes;
 	uint32_t	strip_shift;
 	uint32_t	strip_mask;
-	uint32_t	strip_sizesectors;
-	uint32_t	strip_sizebytes;
+	uint32_t	stripe_sectors;
+	uint32_t	stripe_bytes;
 	uint32_t	rebuild_lba;
 	uint32_t	orig_type;
 	uint32_t	orig_total_sectors;
 	uint32_t	status;
-#define NVIDIA_S_BOOTABLE           0x00000001
-#define NVIDIA_S_DEGRADED           0x00000002
+#define NVIDIA_S_BOOTABLE	0x00000001
+#define NVIDIA_S_DEGRADED	0x00000002
 
 	uint32_t	filler[98];
 } __packed;
@@ -149,7 +155,7 @@ g_raid_md_nvidia_print(struct nvidia_rai
 
 	printf("********* ATA NVidia RAID Metadata *********\n");
 	printf("nvidia_id           <%.8s>\n", meta->nvidia_id);
-	printf("config_size         0x%08x\n", meta->config_size);
+	printf("config_size         %u\n", meta->config_size);
 	printf("checksum            0x%08x\n", meta->checksum);
 	printf("version             0x%04x\n", meta->version);
 	printf("disk_number         %d\n", meta->disk_number);
@@ -160,22 +166,22 @@ g_raid_md_nvidia_print(struct nvidia_rai
 	printf("revision            0x%02x%02x%02x%02x\n",
 	    meta->revision[0], meta->revision[1],
 	    meta->revision[2], meta->revision[3]);
-	printf("dummy_1             0x%08x\n", meta->dummy_1);
+	printf("disk_status         0x%08x\n", meta->disk_status);
 	printf("magic_0             0x%08x\n", meta->magic_0);
 	printf("volume_id           0x%016jx%016jx\n",
-	    meta->volume_id[0], meta->volume_id[1]);
-	printf("flags               0x%02x\n", meta->flags);
+	    meta->volume_id[1], meta->volume_id[0]);
+	printf("state               0x%02x\n", meta->state);
 	printf("array_width         %u\n", meta->array_width);
 	printf("total_disks         %u\n", meta->total_disks);
-	printf("dummy_2             0x%02x\n", meta->dummy_2);
+	printf("orig_array_width    %u\n", meta->orig_array_width);
 	printf("type                0x%04x\n", meta->type);
 	printf("dummy_3             0x%04x\n", meta->dummy_3);
 	printf("strip_sectors       %u\n", meta->strip_sectors);
 	printf("strip_bytes         %u\n", meta->strip_bytes);
 	printf("strip_shift         %u\n", meta->strip_shift);
 	printf("strip_mask          0x%08x\n", meta->strip_mask);
-	printf("strip_sizesectors   %u\n", meta->strip_sizesectors);
-	printf("strip_sizebytes     %u\n", meta->strip_sizebytes);
+	printf("stripe_sectors      %u\n", meta->stripe_sectors);
+	printf("stripe_bytes        %u\n", meta->stripe_bytes);
 	printf("rebuild_lba         %u\n", meta->rebuild_lba);
 	printf("orig_type           0x%04x\n", meta->orig_type);
 	printf("orig_total_sectors  %u\n", meta->orig_total_sectors);
@@ -207,7 +213,6 @@ nvidia_meta_get_name(struct nvidia_raid_
 	}
 }
 
-#if 0
 static void
 nvidia_meta_put_name(struct nvidia_raid_conf *meta, char *buf)
 {
@@ -215,7 +220,6 @@ nvidia_meta_put_name(struct nvidia_raid_
 	memset(meta->name, 0x20, 16);
 	memcpy(meta->name, buf, MIN(strlen(buf), 16));
 }
-#endif
 
 static struct nvidia_raid_conf *
 nvidia_meta_read(struct g_consumer *cp)
@@ -274,6 +278,7 @@ nvidia_meta_read(struct g_consumer *cp)
 	/* Check raid type. */
 	if (meta->type != NVIDIA_T_RAID0 && meta->type != NVIDIA_T_RAID1 &&
 	    meta->type != NVIDIA_T_RAID3 && meta->type != NVIDIA_T_RAID5 &&
+	    meta->type != NVIDIA_T_RAID5_SYM &&
 	    meta->type != NVIDIA_T_RAID10 && meta->type != NVIDIA_T_CONCAT) {
 		G_RAID_DEBUG(1, "NVidia unknown RAID level on %s (0x%02x)",
 		    pp->name, meta->type);
@@ -284,20 +289,20 @@ nvidia_meta_read(struct g_consumer *cp)
 	return (meta);
 }
 
-#if 0
 static int
 nvidia_meta_write(struct g_consumer *cp, struct nvidia_raid_conf *meta)
 {
 	struct g_provider *pp;
 	char *buf;
 	int error, i;
-	uint16_t checksum, *ptr;
+	uint32_t checksum, *ptr;
 
 	pp = cp->provider;
 
 	/* Recalculate checksum for case if metadata were changed. */
 	meta->checksum = 0;
-	for (checksum = 0, ptr = (uint16_t *)meta, i = 0; i < 159; i++)
+	for (checksum = 0, ptr = (uint32_t *)meta,
+	    i = 0; i < meta->config_size; i++)
 		checksum += *ptr++;
 	meta->checksum -= checksum;
 
@@ -305,41 +310,32 @@ nvidia_meta_write(struct g_consumer *cp,
 	buf = malloc(pp->sectorsize, M_MD_NVIDIA, M_WAITOK | M_ZERO);
 	memcpy(buf, meta, sizeof(*meta));
 
-	/* Write 4 copies of metadata. */
-	for (i = 0; i < 4; i++) {
-		error = g_write_data(cp,
-		    pp->mediasize - (pp->sectorsize * (1 + 0x200 * i)),
-		    buf, pp->sectorsize);
-		if (error != 0) {
-			G_RAID_DEBUG(1, "Cannot write metadata to %s (error=%d).",
-			    pp->name, error);
-			break;
-		}
+	/* Write metadata. */
+	error = g_write_data(cp,
+	    pp->mediasize - 2 * pp->sectorsize, buf, pp->sectorsize);
+	if (error != 0) {
+		G_RAID_DEBUG(1, "Cannot write metadata to %s (error=%d).",
+		    pp->name, error);
 	}
 
 	free(buf, M_MD_NVIDIA);
 	return (error);
 }
-#endif
 
 static int
 nvidia_meta_erase(struct g_consumer *cp)
 {
 	struct g_provider *pp;
 	char *buf;
-	int error, i;
+	int error;
 
 	pp = cp->provider;
 	buf = malloc(pp->sectorsize, M_MD_NVIDIA, M_WAITOK | M_ZERO);
-	/* Write 4 copies of metadata. */
-	for (i = 0; i < 4; i++) {
-		error = g_write_data(cp,
-		    pp->mediasize - (pp->sectorsize * (1 + 0x200 * i)),
-		    buf, pp->sectorsize);
-		if (error != 0) {
-			G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).",
-			    pp->name, error);
-		}
+	error = g_write_data(cp,
+	    pp->mediasize - 2 * pp->sectorsize, buf, pp->sectorsize);
+	if (error != 0) {
+		G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).",
+		    pp->name, error);
 	}
 	free(buf, M_MD_NVIDIA);
 	return (error);
@@ -692,6 +688,7 @@ g_raid_md_nvidia_start(struct g_raid_sof
 	nvidia_meta_get_name(meta, buf);
 	vol = g_raid_create_volume(sc, buf, -1);
 	vol->v_mediasize = (off_t)meta->total_sectors * 512;
+	vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE;
 	if (meta->type == NVIDIA_T_RAID0) {
 		vol->v_raid_level = G_RAID_VOLUME_RL_RAID0;
 		size = vol->v_mediasize / mdi->mdio_total_disks;
@@ -710,11 +707,14 @@ g_raid_md_nvidia_start(struct g_raid_sof
 	} else if (meta->type == NVIDIA_T_RAID5) {
 		vol->v_raid_level = G_RAID_VOLUME_RL_RAID5;
 		size = vol->v_mediasize / (mdi->mdio_total_disks - 1);
+	} else if (meta->type == NVIDIA_T_RAID5_SYM) {
+		vol->v_raid_level = G_RAID_VOLUME_RL_RAID5;
+//		vol->v_raid_level_qualifier = 0x03;
+		size = vol->v_mediasize / (mdi->mdio_total_disks - 1);
 	} else {
 		vol->v_raid_level = G_RAID_VOLUME_RL_UNKNOWN;
 		size = 0;
 	}
-	vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE;
 	vol->v_strip_size = meta->strip_sectors * 512; //ZZZ
 	vol->v_disks_count = mdi->mdio_total_disks;
 	vol->v_sectorsize = 512; //ZZZ
@@ -847,8 +847,8 @@ g_raid_md_create_nvidia(struct g_raid_md
 	mdi = (struct g_raid_md_nvidia_object *)md;
 	arc4rand(&mdi->mdio_volume_id, 16, 0);
 	mdi->mdio_generation = 0;
-	snprintf(name, sizeof(name), "NVidia-%016jx%016jx",
-	    mdi->mdio_volume_id[0], mdi->mdio_volume_id[1]);
+	snprintf(name, sizeof(name), "NVidia-%08x",
+	    (uint32_t)mdi->mdio_volume_id[0]);
 	sc = g_raid_create_node(mp, name, md);
 	if (sc == NULL)
 		return (G_RAID_MD_TASTE_FAIL);
@@ -954,8 +954,8 @@ search:
 	} else { /* Not found matching node -- create one. */
 		result = G_RAID_MD_TASTE_NEW;
 		memcpy(&mdi->mdio_volume_id, &meta->volume_id, 16);
-		snprintf(name, sizeof(name), "NVidia-%016jx%016jx",
-		    mdi->mdio_volume_id[0], mdi->mdio_volume_id[1]);
+		snprintf(name, sizeof(name), "NVidia-%08x",
+		    (uint32_t)mdi->mdio_volume_id[0]);
 		sc = g_raid_create_node(mp, name, md);
 		md->mdo_softc = sc;
 		geom = sc->sc_geom;
@@ -1174,7 +1174,7 @@ g_raid_md_ctl_nvidia(struct g_raid_md_ob
 			return (error);
 
 		/* Reserve space for metadata. */
-		size -= 0x800 * sectorsize;
+		size -= 2 * sectorsize;
 
 		/* Handle size argument. */
 		len = sizeof(*sizearg);
@@ -1447,7 +1447,6 @@ static int
 g_raid_md_write_nvidia(struct g_raid_md_object *md, struct g_raid_volume *tvol,
     struct g_raid_subdisk *tsd, struct g_raid_disk *tdisk)
 {
-#if 0
 	struct g_raid_softc *sc;
 	struct g_raid_volume *vol;
 	struct g_raid_subdisk *sd;
@@ -1464,7 +1463,7 @@ g_raid_md_write_nvidia(struct g_raid_md_
 		return (0);
 
 	/* Bump generation. Newly written metadata may differ from previous. */
-	mdi->mdio_generation++;
+//	mdi->mdio_generation++;
 
 	/* There is only one volume. */
 	vol = TAILQ_FIRST(&sc->sc_volumes);
@@ -1473,36 +1472,51 @@ g_raid_md_write_nvidia(struct g_raid_md_
 	meta = malloc(sizeof(*meta), M_MD_NVIDIA, M_WAITOK | M_ZERO);
 	if (mdi->mdio_meta)
 		memcpy(meta, mdi->mdio_meta, sizeof(*meta));
+	memcpy(meta->nvidia_id, NVIDIA_MAGIC, sizeof(NVIDIA_MAGIC));
+	meta->config_size = 30;
+	meta->version = 0x0064;
 	meta->total_sectors = vol->v_mediasize / vol->v_sectorsize;
-	meta->vendor_id = 0x1095;
-	meta->version_minor = 0;
-	meta->version_major = 2;
+	meta->sector_size = vol->v_sectorsize;
+	nvidia_meta_put_name(meta, vol->v_name);
+	meta->magic_0 = NVIDIA_MAGIC0;
 	memcpy(&meta->volume_id, &mdi->mdio_volume_id, 16);
-	meta->strip_sectors = vol->v_strip_size / vol->v_sectorsize;
-	if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID0) {
+	meta->state = NVIDIA_S_IDLE;
+	if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1)
+		meta->array_width = 1;
+	else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E)
+		meta->array_width = vol->v_disks_count / 2;
+	else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID5)
+		meta->array_width = vol->v_disks_count - 1;
+	else
+		meta->array_width = vol->v_disks_count;
+	meta->total_disks = vol->v_disks_count;
+	meta->orig_array_width = meta->array_width;
+	if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID0)
 		meta->type = NVIDIA_T_RAID0;
-		meta->raid0_disks = vol->v_disks_count;
-		meta->raid1_disks = 0xff;
-	} else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1) {
+	else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1)
 		meta->type = NVIDIA_T_RAID1;
-		meta->raid0_disks = 0xff;
-		meta->raid1_disks = vol->v_disks_count;
-	} else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E) {
+	else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E)
 		meta->type = NVIDIA_T_RAID10;
-		meta->raid0_disks = vol->v_disks_count / 2;
-		meta->raid1_disks = 2;
-	} else if (vol->v_raid_level == G_RAID_VOLUME_RL_CONCAT ||
-	    vol->v_raid_level == G_RAID_VOLUME_RL_SINGLE) {
+	else if (vol->v_raid_level == G_RAID_VOLUME_RL_CONCAT ||
+	    vol->v_raid_level == G_RAID_VOLUME_RL_SINGLE)
 		meta->type = NVIDIA_T_CONCAT;
-		meta->raid0_disks = vol->v_disks_count;
-		meta->raid1_disks = 0xff;
-	} else {
-		meta->type = NVIDIA_T_RAID5;
-		meta->raid0_disks = vol->v_disks_count;
-		meta->raid1_disks = 0xff;
-	}
-	meta->generation = mdi->mdio_generation;
-	meta->raid_status = vol->v_dirty ? NVIDIA_S_ONLINE : NVIDIA_S_AVAILABLE;
+//	else if (vol->v_raid_level_qualifier == 0)
+//		meta->type = NVIDIA_T_RAID5;
+	else
+		meta->type = NVIDIA_T_RAID5_SYM;
+	meta->strip_sectors = vol->v_strip_size / vol->v_sectorsize;
+	meta->strip_bytes = vol->v_strip_size;
+	meta->strip_shift = ffs(meta->strip_sectors) - 1;
+	meta->strip_mask = meta->strip_sectors - 1;
+	meta->stripe_sectors = meta->strip_sectors * meta->orig_array_width;
+	meta->stripe_bytes = meta->stripe_sectors * vol->v_sectorsize;
+	meta->rebuild_lba = 0;
+	meta->orig_type = meta->type;
+	meta->orig_total_sectors = meta->total_sectors;
+	meta->status = 0;
+
+//	meta->generation = mdi->mdio_generation;
+/*	meta->raid_status = vol->v_dirty ? NVIDIA_S_ONLINE : NVIDIA_S_AVAILABLE;
 	for (i = 0; i < vol->v_disks_count; i++) {
 		sd = &vol->v_subdisks[i];
 		if (sd->sd_state == G_RAID_SUBDISK_S_STALE ||
@@ -1510,7 +1524,7 @@ g_raid_md_write_nvidia(struct g_raid_md_
 			meta->raid_status = NVIDIA_S_ONLINE;
 	}
 	meta->raid_location = mdi->mdio_location;
-	nvidia_meta_put_name(meta, vol->v_name);
+*/
 
 	/* We are done. Print meta data and store them to disks. */
 	if (mdi->mdio_meta != NULL)
@@ -1527,7 +1541,8 @@ g_raid_md_write_nvidia(struct g_raid_md_
 		}
 		pd->pd_meta = nvidia_meta_copy(meta);
 		if ((sd = TAILQ_FIRST(&disk->d_subdisks)) != NULL) {
-			if (sd->sd_state < G_RAID_SUBDISK_S_NEW)
+			pd->pd_meta->disk_number = sd->sd_pos;
+/*			if (sd->sd_state < G_RAID_SUBDISK_S_NEW)
 				pd->pd_meta->disk_status = NVIDIA_S_DROPPED;
 			else if (sd->sd_state < G_RAID_SUBDISK_S_STALE) {
 				pd->pd_meta->disk_status = NVIDIA_S_REBUILD;
@@ -1535,26 +1550,12 @@ g_raid_md_write_nvidia(struct g_raid_md_
 				    sd->sd_rebuild_pos / vol->v_sectorsize;
 			} else
 				pd->pd_meta->disk_status = NVIDIA_S_CURRENT;
-			if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1) {
-				pd->pd_meta->disk_number = sd->sd_pos;
-				pd->pd_meta->raid0_ident = 0xff;
-				pd->pd_meta->raid1_ident = 0;
-			} else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E) {
-				pd->pd_meta->disk_number = sd->sd_pos / meta->raid1_disks;
-				pd->pd_meta->raid0_ident = sd->sd_pos % meta->raid1_disks;
-				pd->pd_meta->raid1_ident = sd->sd_pos / meta->raid1_disks;
-			} else {
-				pd->pd_meta->disk_number = sd->sd_pos;
-				pd->pd_meta->raid0_ident = 0;
-				pd->pd_meta->raid1_ident = 0xff;
-			}
-		}
+*/		}
 		G_RAID_DEBUG(1, "Writing NVidia metadata to %s",
 		    g_raid_get_diskname(disk));
 		g_raid_md_nvidia_print(pd->pd_meta);
 		nvidia_meta_write(disk->d_consumer, pd->pd_meta);
 	}
-#endif
 	return (0);
 }
 


More information about the svn-src-projects mailing list