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

Alexander Motin mav at FreeBSD.org
Tue Mar 22 22:39:42 UTC 2011


Author: mav
Date: Tue Mar 22 22:39:42 2011
New Revision: 219890
URL: http://svn.freebsd.org/changeset/base/219890

Log:
  Improve NVidia metadata reading and writing.

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 21:39:57 2011	(r219889)
+++ projects/graid/head/sys/geom/raid/md_nvidia.c	Tue Mar 22 22:39:42 2011	(r219890)
@@ -73,6 +73,7 @@ struct nvidia_raid_conf {
 	uint8_t		total_disks;
 	uint8_t		orig_array_width;
 	uint16_t	type;
+#define NVIDIA_T_UNKNOWN	0x0000
 #define NVIDIA_T_RAID0		0x0080
 #define NVIDIA_T_RAID1		0x0081
 #define NVIDIA_T_RAID3		0x0083
@@ -107,8 +108,6 @@ struct g_raid_md_nvidia_perdisk {
 struct g_raid_md_nvidia_object {
 	struct g_raid_md_object	 mdio_base;
 	uint64_t		 mdio_volume_id[2];
-	uint8_t			 mdio_location;
-	uint32_t		 mdio_generation;
 	struct nvidia_raid_conf	*mdio_meta;
 	struct callout		 mdio_start_co;	/* STARTING state timer. */
 	int			 mdio_total_disks;
@@ -344,27 +343,18 @@ nvidia_meta_erase(struct g_consumer *cp)
 static int
 nvidia_meta_write_spare(struct g_consumer *cp)
 {
-#if 0
 	struct nvidia_raid_conf *meta;
 	int error;
 
 	meta = malloc(sizeof(*meta), M_MD_NVIDIA, M_WAITOK | M_ZERO);
-	meta->total_sectors = cp->provider->mediasize /
-	    cp->provider->sectorsize - 0x800;
-	meta->vendor_id = 0x1095;
-	meta->version_minor = 0;
-	meta->version_major = 2;
-	meta->volume_id[0] = arc4random();
-	meta->volume_id[1] = arc4random();
-	meta->type = NVIDIA_T_SPARE;
-	meta->generation = 1;
-	meta->raid1_ident = 0xff;
-	meta->raid_location = arc4random();
+	memcpy(meta->nvidia_id, NVIDIA_MAGIC, sizeof(NVIDIA_MAGIC));
+	meta->config_size = 30;
+	meta->version = 0x0064;
+	meta->magic_0 = NVIDIA_MAGIC0;
+	meta->type = NVIDIA_T_UNKNOWN;
 	error = nvidia_meta_write(cp, meta);
 	free(meta, M_MD_NVIDIA);
 	return (error);
-#endif
-	return (0);
 }
 
 static struct g_raid_disk *
@@ -465,7 +455,7 @@ g_raid_md_nvidia_start_disk(struct g_rai
 				continue;
 			/* Make sure this disk is big enough. */
 			TAILQ_FOREACH(sd, &tmpdisk->d_subdisks, sd_next) {
-				if (sd->sd_offset + sd->sd_size + 512 >
+				if (sd->sd_offset + sd->sd_size + 2 * 512 >
 				    pd->pd_disk_size) {
 					G_RAID_DEBUG1(1, sc,
 					    "Disk too small (%ju < %ju)",
@@ -551,32 +541,31 @@ nofit:
 			/* New or ex-spare disk. */
 			g_raid_change_subdisk_state(sd,
 			    G_RAID_SUBDISK_S_NEW);
-#if 0
-		} else if (pd->pd_meta->disk_status == NVIDIA_S_REBUILD) {
+		} else if (mdi->mdio_started) {
+			/*
+			 * As soon as we have no generations - treat
+			 * treat every hot-plugged disk as new.
+			 */
+			g_raid_change_subdisk_state(sd,
+			    G_RAID_SUBDISK_S_NEW);
+		} else if (meta->state == NVIDIA_S_REBUILD &&
+		    (pd->pd_meta->disk_status & 0x100)) {
 			/* Rebuilding disk. */
 			g_raid_change_subdisk_state(sd,
 			    G_RAID_SUBDISK_S_REBUILD);
-			if (pd->pd_meta->generation == meta->generation)
-				sd->sd_rebuild_pos = pd->pd_meta->rebuild_lba * 512;
-			else
-				sd->sd_rebuild_pos = 0;
-		} else if (pd->pd_meta->disk_status == NVIDIA_S_CURRENT) {
-			if (pd->pd_meta->raid_status == NVIDIA_S_ONLINE ||
-			    pd->pd_meta->generation != meta->generation) {
-				/* Dirty or resyncing disk. */
-				g_raid_change_subdisk_state(sd,
-				    G_RAID_SUBDISK_S_STALE);
-#endif
-			} else {
-				/* Up to date disk. */
-				g_raid_change_subdisk_state(sd,
-				    G_RAID_SUBDISK_S_ACTIVE);
-#if 0
-			}
+			sd->sd_rebuild_pos = pd->pd_meta->rebuild_lba *
+			    pd->pd_meta->sector_size;
+		} else if (meta->state == NVIDIA_S_SYNC &&
+		    (pd->pd_meta->disk_status & 0x100)) {
+			/* Resyncing disk. */
+			g_raid_change_subdisk_state(sd,
+			    G_RAID_SUBDISK_S_RESYNC);
+			sd->sd_rebuild_pos = pd->pd_meta->rebuild_lba *
+			    pd->pd_meta->sector_size;
 		} else {
+			/* Up to date disk. */
 			g_raid_change_subdisk_state(sd,
-			    G_RAID_SUBDISK_S_FAILED);
-#endif
+			    G_RAID_SUBDISK_S_ACTIVE);
 		}
 		g_raid_event_send(sd, G_RAID_SUBDISK_E_NEW,
 		    G_RAID_EVENT_SUBDISK);
@@ -674,10 +663,9 @@ g_raid_md_nvidia_start(struct g_raid_sof
 	struct nvidia_raid_conf *meta;
 	struct g_raid_volume *vol;
 	struct g_raid_subdisk *sd;
-	struct g_raid_disk *disk, *best;
+	struct g_raid_disk *disk;
 	off_t size;
 	int j, disk_pos;
-	uint32_t gendiff, bestgendiff;
 	char buf[17];
 
 	md = sc->sc_md;
@@ -737,30 +725,15 @@ g_raid_md_nvidia_start(struct g_raid_sof
 		TAILQ_INSERT_TAIL(&disk->d_subdisks, sd, sd_next);
 	}
 
-	/*
-	 * Make all disks found till the moment take their places
-	 * in order of their generation numbers.
-	 */
+	/* Make all disks found till the moment take their places. */
 	do {
-		best = NULL;
-		bestgendiff = 0xffffffff;
 		TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
-			if (disk->d_state != G_RAID_DISK_S_NONE)
-				continue;
-			pd = disk->d_md_data;
-			if (pd->pd_meta == NULL)
-				gendiff = 0xfffffffe;
-			else
-				gendiff = 0;//meta->generation -
-				    //pd->pd_meta->generation;
-			if (gendiff < bestgendiff) {
-				best = disk;
-				bestgendiff = gendiff;
+			if (disk->d_state == G_RAID_DISK_S_NONE) {
+				g_raid_md_nvidia_start_disk(disk);
+				break;
 			}
 		}
-		if (best != NULL)
-			g_raid_md_nvidia_start_disk(best);
-	} while (best != NULL);
+	} while (disk != NULL);
 
 	mdi->mdio_started = 1;
 	G_RAID_DEBUG1(0, sc, "Array started.");
@@ -796,22 +769,18 @@ g_raid_md_nvidia_new_disk(struct g_raid_
 		if (g_raid_md_nvidia_start_disk(disk))
 			g_raid_md_write_nvidia(md, NULL, NULL, NULL);
 	} else {
-		if (mdi->mdio_meta == NULL/* ||
-		    ((int32_t)(pdmeta->generation - mdi->mdio_generation)) > 0*/) {
+		if (mdi->mdio_meta == NULL) {
 			G_RAID_DEBUG1(1, sc, "Newer disk");
 			if (mdi->mdio_meta != NULL)
 				free(mdi->mdio_meta, M_MD_NVIDIA);
 			mdi->mdio_meta = nvidia_meta_copy(pdmeta);
-//			mdi->mdio_generation = mdi->mdio_meta->generation;
 			mdi->mdio_total_disks = pdmeta->total_disks;
 			mdi->mdio_disks_present = 1;
-		} else /*if (pdmeta->generation == mdi->mdio_generation)*/ {
+		} else {
 			mdi->mdio_disks_present++;
 			G_RAID_DEBUG1(1, sc, "Matching disk (%d of %d up)",
 			    mdi->mdio_disks_present,
 			    mdi->mdio_total_disks);
-//		} else {
-//			G_RAID_DEBUG1(1, sc, "Older disk");
 		}
 
 		/* If we collected all needed disks - start array. */
@@ -846,7 +815,6 @@ 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-%08x",
 	    (uint32_t)mdi->mdio_volume_id[0]);
 	sc = g_raid_create_node(mp, name, md);
@@ -1462,9 +1430,6 @@ g_raid_md_write_nvidia(struct g_raid_md_
 	if (sc->sc_stopping == G_RAID_DESTROY_HARD)
 		return (0);
 
-	/* Bump generation. Newly written metadata may differ from previous. */
-//	mdi->mdio_generation++;
-
 	/* There is only one volume. */
 	vol = TAILQ_FIRST(&sc->sc_volumes);
 
@@ -1515,16 +1480,16 @@ g_raid_md_write_nvidia(struct g_raid_md_
 	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 ||
-		    sd->sd_state == G_RAID_SUBDISK_S_RESYNC)
-			meta->raid_status = NVIDIA_S_ONLINE;
+		if ((sd->sd_state == G_RAID_SUBDISK_S_STALE ||
+		     sd->sd_state == G_RAID_SUBDISK_S_RESYNC) &&
+		     meta->state != NVIDIA_S_REBUILD)
+			meta->state = NVIDIA_S_SYNC;
+		else if (sd->sd_state == G_RAID_SUBDISK_S_NEW ||
+		     sd->sd_state == G_RAID_SUBDISK_S_REBUILD)
+			meta->state = NVIDIA_S_REBUILD;
 	}
-	meta->raid_location = mdi->mdio_location;
-*/
 
 	/* We are done. Print meta data and store them to disks. */
 	if (mdi->mdio_meta != NULL)
@@ -1542,15 +1507,12 @@ g_raid_md_write_nvidia(struct g_raid_md_
 		pd->pd_meta = nvidia_meta_copy(meta);
 		if ((sd = TAILQ_FIRST(&disk->d_subdisks)) != NULL) {
 			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;
+			if (sd->sd_state != G_RAID_SUBDISK_S_ACTIVE) {
+				pd->pd_meta->disk_status = 0x100;
 				pd->pd_meta->rebuild_lba =
 				    sd->sd_rebuild_pos / vol->v_sectorsize;
-			} else
-				pd->pd_meta->disk_status = NVIDIA_S_CURRENT;
-*/		}
+			}
+		}
 		G_RAID_DEBUG(1, "Writing NVidia metadata to %s",
 		    g_raid_get_diskname(disk));
 		g_raid_md_nvidia_print(pd->pd_meta);
@@ -1563,7 +1525,6 @@ static int
 g_raid_md_fail_disk_nvidia(struct g_raid_md_object *md,
     struct g_raid_subdisk *tsd, struct g_raid_disk *tdisk)
 {
-#if 0
 	struct g_raid_softc *sc;
 	struct g_raid_md_nvidia_object *mdi;
 	struct g_raid_md_nvidia_perdisk *pd;
@@ -1577,17 +1538,9 @@ g_raid_md_fail_disk_nvidia(struct g_raid
 	if (pd->pd_disk_pos < 0)
 		return (-1);
 
-	/*
-	 * Mark disk as failed in metadata and try to write that metadata
-	 * to the disk itself to prevent it's later resurrection as STALE.
-	 */
-	if (tdisk->d_consumer) {
-		if (pd->pd_meta) {
-			pd->pd_meta->disk_status = NVIDIA_S_REMOVED;
-			nvidia_meta_write(tdisk->d_consumer, pd->pd_meta);
-		} else
-			nvidia_meta_erase(tdisk->d_consumer);
-	}
+	/* Erase metadata to prevent disks's later resurrection. */
+	if (tdisk->d_consumer)
+		nvidia_meta_erase(tdisk->d_consumer);
 
 	/* Change states. */
 	g_raid_change_disk_state(tdisk, G_RAID_DISK_S_FAILED);
@@ -1607,7 +1560,6 @@ g_raid_md_fail_disk_nvidia(struct g_raid
 		g_raid_destroy_node(sc, 0);
 	else
 		g_raid_md_nvidia_refill(sc);
-#endif
 	return (0);
 }
 


More information about the svn-src-projects mailing list