[PATCH] v2 of Adaptec HostRAID support for dmraid

Heinz Mauelshagen mauelshagen at redhat.com
Wed Jan 11 10:35:50 UTC 2006


On Tue, Jan 10, 2006 at 04:36:10PM -0800, Darrick J. Wong wrote:
> All,
> 
> This is a revised patch to add HostRAID support to dmraid.  It contains
> a reworked asr_group function that knows how to set up multilevel RAID
> 10, as well as the usual RAID0 / RAID1 cases.  It has seen somewhat
> rigorous testing in RAID0/1/10 setups on a SCSI HostRAID x226 and very
> light testing on SATA HostRAID on the same machine.  Last Friday I was
> able to convert a a320raid based SLES9 SP2 system to a dmraid setup, and
> verified that I could (with some difficulty) bring up the system.
> 
> Note that spare drives, metadata writes and I/O error handling are still
> not implemented.
> 
> Mr. Mauelshagen: Was it ok to add subordinate raid_sets to the master
> raid_set manually with list_add?

Sure, Mr. Wong :)

Please check though, if you can use join_superset() to streamline
the grouping logic in asr_group().

Attached is a (20min quick path) dmraid-asr_3.patch against
your dmraid-asr_2.patch which does:

o avoid some memory leaks
o use HANDLER where appropriate
o avoid asr_ prefixes on internal functions
o use CVT* macros as the rest of the metadata format handlers
o pretty print

Please check if I've broken something ;-)

Heinz

> 
> As usual, I'm looking for any comments or suggestions about how to
> improve this code.  This patch should not be used in a production system
> at all.
> 
> --D





> _______________________________________________
> Ataraid-list mailing list
> Ataraid-list at redhat.com
> https://www.redhat.com/mailman/listinfo/ataraid-list

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Heinz Mauelshagen                                 Red Hat GmbH
Consulting Development Engineer                   Am Sonnenhang 11
Cluster and Storage Development                   56242 Marienrachdorf
                                                  Germany
Mauelshagen at RedHat.com                            +49 2626 141200
                                                       FAX 924446
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-------------- next part --------------
--- current/lib/format/ataraid/asr.c.Darrick_J._Wong	2006-01-11 11:12:23.000000000 +0100
+++ current/lib/format/ataraid/asr.c	2006-01-11 11:32:50.000000000 +0100
@@ -18,59 +18,65 @@
 static const char *handler = HANDLER;
 
 /* Map ASR disk status to dmraid status */
-static enum status asr_disk_status(struct asr_raid_configline *disk) {
+static enum status disk_status(struct asr_raid_configline *disk) {
 	if (disk == NULL)
 		return s_undef;
 
 	switch (disk->raidstate) {
-		case LSU_COMPONENT_STATE_OPTIMAL:
-			return s_ok;
-		case LSU_COMPONENT_STATE_DEGRADED:
-		case LSU_COMPONENT_STATE_FAILED:
-			return s_broken;
-		case LSU_COMPONENT_STATE_UNINITIALIZED:
-		case LSU_COMPONENT_STATE_UNCONFIGURED:
-			return s_inconsistent;
-		case LSU_COMPONENT_SUBSTATE_BUILDING:
-		case LSU_COMPONENT_SUBSTATE_REBUILDING:
-		case LSU_COMPONENT_STATE_REPLACED:
-			return s_nosync;
-		default:
-			return s_undef;
+	case LSU_COMPONENT_STATE_OPTIMAL:
+		return s_ok;
+
+	case LSU_COMPONENT_STATE_DEGRADED:
+	case LSU_COMPONENT_STATE_FAILED:
+		return s_broken;
+
+	case LSU_COMPONENT_STATE_UNINITIALIZED:
+	case LSU_COMPONENT_STATE_UNCONFIGURED:
+		return s_inconsistent;
+
+	case LSU_COMPONENT_SUBSTATE_BUILDING:
+	case LSU_COMPONENT_SUBSTATE_REBUILDING:
+	case LSU_COMPONENT_STATE_REPLACED:
+		return s_nosync;
+
+	default:
+		return s_undef;
 	}
 }
 		
 /* Extract config line from metadata */
-static struct asr_raid_configline *asr_get_config(struct asr *asr, uint32_t magic)
+static struct asr_raid_configline *get_config(struct asr *asr, uint32_t magic)
 {
 	unsigned int i;
 	
 	for (i = 0; i < asr->rt.elmcnt; i++) {
 		if (asr->rt.ent[i].raidmagic == magic)
-			return &asr->rt.ent[i];
+			return asr->rt.ent + i;
 	}
 
 	return NULL;
 }
 
 /* Get this disk's configuration */
-static struct asr_raid_configline *asr_this_disk(struct asr *asr) {
-	return asr_get_config(asr, asr->rb.drivemagic);
+static struct asr_raid_configline *this_disk(struct asr *asr)
+{
+	return get_config(asr, asr->rb.drivemagic);
 }
 
 /* Make up RAID device name. */
 static size_t _name(struct lib_context *lc, struct asr *asr, char *str,
-	size_t len)
+		    size_t len)
 {
-	struct asr_raid_configline *cl = asr_this_disk(asr);
-	if (cl == NULL)
-		LOG_ERR(lc, 0, "%s: Could not find device in config table!\n",
-			handler);
-	return snprintf(str, len, "asr_%s", cl->name);
+	struct asr_raid_configline *cl = this_disk(asr);
+
+	if (cl)
+		return snprintf(str, len, "%s_%s", HANDLER, cl->name);
+
+	LOG_ERR(lc, 0, "%s: Could not find device in config table!", handler);
 }
 
 /* Figure out a name for the RAID device. */
-static char *asr_name(struct lib_context *lc, struct asr *asr)
+static char *name(struct lib_context *lc, struct asr *asr)
 {
 	size_t len;
 	char *ret;
@@ -100,88 +106,87 @@
 };
 
 /* Map the ASR raid type codes into dmraid type codes. */
-static enum type asr_type(struct asr_raid_configline *cl)
+static enum type type(struct asr_raid_configline *cl)
 {
-	return cl ? rd_type(types, (unsigned int)cl->raidtype) : t_undef;
+	return cl ? rd_type(types, (unsigned int) cl->raidtype) : t_undef;
 }
 
 /*
  * Read an ASR RAID device.  Fields are big endian, so
  * need to convert them if we're on a LE machine (i386, etc).
  */
-#define ASR_BLOCK	1
-#define ASR_TABLE	2
-#define ASR_EXTTABLE 	4
+#define ASR_BLOCK	0x01
+#define ASR_TABLE	0x02
+#define ASR_EXTTABLE 	0x04
 
 #if	BYTE_ORDER == LITTLE_ENDIAN
 
-static void cvt_configline(struct asr_raid_configline *cline)
+static void cvt_configline(struct asr_raid_configline *cl)
 {
-	cline->raidcnt		= ntohs(cline->raidcnt);
-	cline->raidseq		= ntohs(cline->raidseq);
-	cline->raidmagic	= ntohl(cline->raidmagic);
-	cline->raidid		= ntohl(cline->raidid);
-	cline->loffset		= ntohl(cline->loffset);
-	cline->lcapcty		= ntohl(cline->lcapcty);
-	cline->strpsize		= ntohs(cline->strpsize);
-	cline->biosInfo		= ntohs(cline->biosInfo);
-	cline->lsu		= ntohl(cline->lsu);
-	cline->blockStorageTid	= ntohs(cline->blockStorageTid);
-	cline->curAppBlock	= ntohl(cline->curAppBlock);
-	cline->appBurstCount	= ntohl(cline->appBurstCount);
+	CVT16(cl->raidcnt);
+	CVT16(cl->raidseq);
+	CVT32(cl->raidmagic);
+	CVT32(cl->raidid);
+	CVT32(cl->loffset);
+	CVT32(cl->lcapcty);
+	CVT16(cl->strpsize);
+	CVT16(cl->biosInfo);
+	CVT32(cl->lsu);
+	CVT16(cl->blockStorageTid);
+	CVT32(cl->curAppBlock);
+	CVT32(cl->appBurstCount);
 }
 
-static void to_cpu(void *meta, unsigned int cvt) {
-	struct asr *asr = meta;
+static void to_cpu(void *meta, unsigned int cvt)
+{
 	int i;
+	struct asr *asr = meta;
 
 	if (cvt & ASR_BLOCK) {
-		asr->rb.b0idcode	= ntohl(asr->rb.b0idcode);
-		asr->rb.biosInfo	= ntohs(asr->rb.biosInfo);
-		asr->rb.fstrsvrb	= ntohl(asr->rb.fstrsvrb);
-		asr->rb.svBlockStorageTid
-					= ntohs(asr->rb.svBlockStorageTid);
-		asr->rb.svtid		= ntohs(asr->rb.svtid);
-		asr->rb.drivemagic	= ntohl(asr->rb.drivemagic);
-		asr->rb.fwTestMagic	= ntohl(asr->rb.fwTestMagic);
-		asr->rb.fwTestSeqNum	= ntohl(asr->rb.fwTestSeqNum);
-		asr->rb.smagic		= ntohl(asr->rb.smagic);
-		asr->rb.raidtbl		= ntohl(asr->rb.raidtbl);
+		CVT32(asr->rb.b0idcode);
+		CVT16(asr->rb.biosInfo);
+		CVT32(asr->rb.fstrsvrb);
+		CVT16(asr->rb.svBlockStorageTid);
+		CVT16(asr->rb.svtid);
+		CVT32(asr->rb.drivemagic);
+		CVT32(asr->rb.fwTestMagic);
+		CVT32(asr->rb.fwTestSeqNum);
+		CVT32(asr->rb.smagic);
+		CVT32(asr->rb.raidtbl);
 	}
 
 	if (cvt & ASR_TABLE) {
-		asr->rt.ridcode		= ntohl(asr->rt.ridcode);
-		asr->rt.rversion	= ntohl(asr->rt.rversion);
-		asr->rt.maxelm		= ntohs(asr->rt.maxelm);
-		asr->rt.elmcnt		= ntohs(asr->rt.elmcnt);
-		asr->rt.elmsize		= ntohs(asr->rt.elmsize);
-		asr->rt.raidFlags	= ntohl(asr->rt.raidFlags);
-		asr->rt.timestamp	= ntohl(asr->rt.timestamp);
-		asr->rt.rchksum		= ntohs(asr->rt.rchksum);
-		asr->rt.sparedrivemagic	= ntohl(asr->rt.sparedrivemagic);
-		asr->rt.raidmagic	= ntohl(asr->rt.raidmagic);
-		asr->rt.verifyDate	= ntohl(asr->rt.verifyDate);
-		asr->rt.recreateDate	= ntohl(asr->rt.recreateDate);
+		CVT32(asr->rt.ridcode);
+		CVT32(asr->rt.rversion);
+		CVT16(asr->rt.maxelm);
+		CVT16(asr->rt.elmcnt);
+		CVT16(asr->rt.elmsize);
+		CVT32(asr->rt.raidFlags);
+		CVT32(asr->rt.timestamp);
+		CVT16(asr->rt.rchksum);
+		CVT32(asr->rt.sparedrivemagic);
+		CVT32(asr->rt.raidmagic);
+		CVT32(asr->rt.verifyDate);
+		CVT32(asr->rt.recreateDate);
 
 		/* Convert the first seven config lines */
-		for (i = 0; i < (asr->rt.elmcnt < 7 ? asr->rt.elmcnt : 7); i++) {
-			cvt_configline(&asr->rt.ent[i]);
-		}
+		for (i = 0; i < (asr->rt.elmcnt < 7 ? asr->rt.elmcnt : 7); i++) 
+			cvt_configline(asr->rt.ent + i);
 		
 	}
 
 	if (cvt & ASR_EXTTABLE) {
-		for (i = 7; i < asr->rt.elmcnt; i++) {
-			cvt_configline(&asr->rt.ent[i]);
-		}
+		for (i = 7; i < asr->rt.elmcnt; i++)
+			cvt_configline(asr->rt.ent + i);
 	}
 }
+
 #else
 # define to_cpu(x, y)
 #endif
 
-static int asr_read_extended(struct lib_context *lc, struct dev_info *di,
-	struct asr *asr)
+static int read_extended(struct lib_context *lc, struct dev_info *di,
+			 struct asr *asr)
 {
 	unsigned int remaining, i, checksum;
 	int j;
@@ -191,10 +196,8 @@
 	
 	/* Read the RAID table. */
 	if (!read_file(lc, handler, di->path, &asr->rt, ASR_DISK_BLOCK_SIZE,
-		(uint64_t)asr->rb.raidtbl * ASR_DISK_BLOCK_SIZE))
-	{
+		       (uint64_t) asr->rb.raidtbl * ASR_DISK_BLOCK_SIZE))
 		LOG_ERR(lc, 0, "%s: Could not read metadata.", handler);
-	}
 
 	/* Convert it */
 	to_cpu(asr, ASR_TABLE);
@@ -217,24 +220,25 @@
 	/* Figure out how much else we need to read. */
 	if (asr->rt.elmcnt > 7) {
 		remaining = asr->rt.elmsize * (asr->rt.elmcnt - 7);
-		if (!read_file(lc, handler, di->path, &asr->rt.ent[7],
-			remaining,
-			(uint64_t)(asr->rb.raidtbl + 1) * ASR_DISK_BLOCK_SIZE))
-		{
+		if (!read_file(lc, handler, di->path, asr->rt.ent + 7,
+			       remaining, (uint64_t)(asr->rb.raidtbl + 1) *
+			       ASR_DISK_BLOCK_SIZE))
 			return 0;
-		}
+
 		to_cpu(asr, ASR_EXTTABLE);
 	}
 
 	/* Compute checksum. */
-	ptr = (uint8_t *)asr->rt.ent;
+	ptr = (uint8_t*) asr->rt.ent;
 	checksum = 0;
-	for (i = 0; i < sizeof(asr->rt.ent[0]) * asr->rt.elmcnt; i++) {
+	for (i = 0; i < sizeof(*asr->rt.ent) * asr->rt.elmcnt; i++)
 		checksum += ptr[i];
-	}
+
 	checksum &= 0xFFFF;
+
 	if (checksum != asr->rt.rchksum)
-		LOG_ERR(lc, 0, "%s: Invalid RAID config table checksum (0x%X vs. 0x%X).\n",
+		LOG_ERR(lc, 0,"%s: Invalid RAID config table checksum "
+			       "(0x%X vs. 0x%X).",
 			handler, checksum, asr->rt.rchksum);
 	
 	/* Process the name of each line of the config line. */
@@ -258,7 +262,7 @@
 		 *
 		 * This is nuts.
 		 */
-		if (asr->rt.ent[i].name == 0)
+		if (!asr->rt.ent[i].name)
 			memcpy(asr->rt.ent[i].name, asr->rt.ent[0].name, 16);
 
 		/* Now truncate trailing whitespace in the name. */
@@ -275,14 +279,17 @@
 {
 	struct asr *asr = meta;
 
-	/* Check our magic numbers and that the version == v8.
-	 * We don't support anything other than that right now. */
-	if (asr->rb.b0idcode == B0RESRVD && asr->rb.smagic == SVALID) {
-		if (asr->rb.resver == RBLOCK_VER) {
+	/*
+	 * Check our magic numbers and that the version == v8.
+	 * We don't support anything other than that right now.
+	 */
+	if (asr->rb.b0idcode == B0RESRVD &&
+	    asr->rb.smagic == SVALID) {
+		if (asr->rb.resver == RBLOCK_VER)
 			return 1;
-		}
 		
-		LOG_ERR(lc, 0, "%s: ASR v%d detected, but we only support v8.\n",
+		LOG_ERR(lc, 0,
+			"%s: ASR v%d detected, but we only support v8.\n",
 			handler, asr->rb.resver);
 	}
 
@@ -302,9 +309,9 @@
  * lacks this sort of visibility as to where its block devices come from.
  * This is EXTREMELY DANGEROUS if you aren't careful!
  */
-static void *asr_read_metadata(struct lib_context *lc, struct dev_info *di,
-			       size_t *sz, uint64_t *offset,
-			       union read_info *info)
+static void *read_metadata_areas(struct lib_context *lc, struct dev_info *di,
+				 size_t *sz, uint64_t *offset,
+				 union read_info *info)
 {
 	size_t size = ASR_DISK_BLOCK_SIZE;
 	uint64_t asr_sboffset = ASR_CONFIGOFFSET;
@@ -316,10 +323,8 @@
 	 * the two magic numbers, the version, and the pointer to the
 	 * RAID table.  Everything else appears to be unused in v8.
 	 */
-	asr = alloc_private(lc, handler, sizeof(struct asr));
-	if (!asr) {
+	if (!(asr = alloc_private(lc, handler, sizeof(struct asr))))
 		goto out;
-	}
 
 	if (!read_file(lc, handler, di->path, &asr->rb, size, asr_sboffset))
 		goto bad;
@@ -331,7 +336,7 @@
 
 	/* Check Signature and read optional extended metadata. */
 	if (!is_asr(lc, di, asr) ||
-	    !asr_read_extended(lc, di, asr))
+	    !read_extended(lc, di, asr))
 		goto bad;
 
 	/*
@@ -340,6 +345,7 @@
 	 * we ignore a s_broken drive?
 	 */
 	goto out;
+
    bad:
 	dbg_free(asr);
 	asr = NULL;
@@ -352,8 +358,8 @@
  * "File the metadata areas" -- I think this function is supposed to declare
  * which parts of the drive are metadata and thus off-limits to dmraid.
  */
-static void asr_file_metadata(struct lib_context *lc, struct dev_info *di,
-	void *meta)
+static void file_metadata_areas(struct lib_context *lc, struct dev_info *di,
+				void *meta)
 {
 	struct asr *asr = meta;
 	
@@ -364,86 +370,76 @@
 
 	/* Register the reserved block. */
 	file_metadata(lc, handler, di->path, &asr->rb, ASR_DISK_BLOCK_SIZE,
-		ASR_CONFIGOFFSET);
+		      ASR_CONFIGOFFSET);
 
 	/* Register the raid table. */
 	file_metadata(lc, handler, di->path, &asr->rt, ASR_DISK_BLOCK_SIZE,
-		(uint64_t)asr->rb.raidtbl * ASR_DISK_BLOCK_SIZE);
+		      (uint64_t) asr->rb.raidtbl * ASR_DISK_BLOCK_SIZE);
 
 	/*
 	 * Register the rest of the config table.  We need to register
 	 * all the space (i.e. maxelm), not just what we're using now.
 	 */
 	if (asr->rt.maxelm > 7)
-		file_metadata(lc, handler, di->path, &asr->rt.ent[7],
-			(asr->rt.maxelm-7) * sizeof(struct asr_raid_configline),
-			(uint64_t)(asr->rb.raidtbl+1) * ASR_DISK_BLOCK_SIZE);
+		file_metadata(lc, handler, di->path, asr->rt.ent + 7,
+			      (asr->rt.maxelm - 7) *
+			      sizeof(struct asr_raid_configline),
+			      (uint64_t) (asr->rb.raidtbl + 1) *
+			      ASR_DISK_BLOCK_SIZE);
 
 
-	/* I have no idea what this does */
+	/* File the device size if option -D */
 	file_dev_size(lc, handler, di);
 }
 
-static int asr_setup_rd(struct lib_context *lc, struct raid_dev *rd,
-		    struct dev_info *di, void *meta, union read_info *info);
-
+static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
+	            struct dev_info *di, void *meta, union read_info *info);
 static struct raid_dev *asr_read(struct lib_context *lc,
 					struct dev_info *di)
 {
 	/*
-	 * NOTE: Everything called after asr_read_metadata assumes that
+	 * NOTE: Everything called after read_metadata_areas assumes that
 	 * the reserved block, raid table and config table have been
 	 * converted to the appropriate endianness.
 	 */
-	return read_raid_dev(lc, di, asr_read_metadata, 0, 0, NULL, NULL,
-		asr_file_metadata, asr_setup_rd, handler);
+	return read_raid_dev(lc, di, read_metadata_areas, 0, 0, NULL, NULL,
+			     file_metadata_areas, setup_rd, handler);
 }
 
-static int no_sort(struct list_head *dont, struct list_head *care)
+static int set_sort(struct list_head *pos, struct list_head *new)
 {
 	return 0;
 }
 
-/* Sort ASR devices by for a RAID set. */
-static int asr_dev_sort(struct list_head *pos, struct list_head *new)
+/* Is using a 64-bit id composed of hba:ch:lun:id ok? */
+static inline uint64_t compose_id(struct asr_raid_configline *cl)
 {
-	struct asr_raid_configline *p, *n;
-	uint64_t one, two;
-
-	p = asr_this_disk( META(RD(pos), asr) );
-	n = asr_this_disk( META(RD(new), asr) );
-
-	/* Is using a 64-bit id composed of hba:ch:lun:id ok? */
-	one =     ((uint64_t)n->raidhba << 48)
-		| ((uint64_t)n->raidchnl << 40)
-		| ((uint64_t)n->raidlun << 32)
-		| ((uint64_t)n->raidid);
-
-	two =     ((uint64_t)p->raidhba << 48)
-		| ((uint64_t)p->raidchnl << 40)
-		| ((uint64_t)p->raidlun << 32)
-		| ((uint64_t)p->raidid);
+	return    ((uint64_t) cl->raidhba << 48)
+		| ((uint64_t) cl->raidchnl << 40)
+		| ((uint64_t) cl->raidlun << 32)
+		| (uint64_t) cl->raidid;
+}
 
-	return (one < two);
+/* Sort ASR devices by for a RAID set. */
+static int dev_sort(struct list_head *pos, struct list_head *new)
+{
+	return compose_id(this_disk(META(RD(new), asr))) <
+	       compose_id(this_disk(META(RD(pos), asr)));
 }
 
 /*
  * Find the top-level RAID set for an ASR context.
  */
-static int asr_find_toplevel(struct lib_context *lc,
-		struct asr *asr)
+static int find_toplevel(struct lib_context *lc, struct asr *asr)
 {
 	int i, toplevel = -1;
 
 	for (i = 0; i < asr->rt.elmcnt; i++) {
-		if (asr->rt.ent[i].raidlevel == FWL_2)
-		{
+		if (asr->rt.ent[i].raidlevel == FWL)
 			toplevel = i;
-			break;
-		}
-		else if (asr->rt.ent[i].raidlevel == FWL)
-		{
+		else if (asr->rt.ent[i].raidlevel == FWL_2) {
 			toplevel = i;
+			break;
 		}
 	}
 	
@@ -454,17 +450,16 @@
  * Find the logical drive configuration that goes with this
  * physical disk configuration.
  */
-static struct asr_raid_configline *asr_find_logical(struct asr *asr)
+static struct asr_raid_configline *find_logical(struct asr *asr)
 {
 	int i, j;
 
 	/* This MUST be done backwards! */
-	for (i = asr->rt.elmcnt - 1; i >= 0; i--) {
+	for (i = asr->rt.elmcnt - 1; i > -1; i--) {
 		if (asr->rt.ent[i].raidmagic == asr->rb.drivemagic) {
-			for (j = i - 1; j >= 0; j--) {
-				if (asr->rt.ent[j].raidlevel == FWL) {
-					return &asr->rt.ent[j];
-				}
+			for (j = i - 1; j > -1; j--) {
+				if (asr->rt.ent[j].raidlevel == FWL)
+					return asr->rt.ent + j;
 			}
 		}
 	}
@@ -480,51 +475,51 @@
  *
  * FIXME: Actually, HostRAID _does_ do multilevel RAID (10).
  */
-static struct raid_set *asr_group(struct lib_context *lc,
-		struct raid_dev *rd)
+#define BUF_SIZE	64
+static struct raid_set *asr_group(struct lib_context *lc, struct raid_dev *rd)
 {
 	int top_idx, i;
+	char *asr_name, inbuf[BUF_SIZE], *outbuf;
 	struct raid_set *top_set, *set = NULL, *tmp;
 	struct asr *asr = META(rd, asr);
-	struct asr_raid_configline *cl = asr_this_disk(asr);
+	struct asr_raid_configline *cl = this_disk(asr);
 	struct asr_raid_configline *fwl;
-	char inbuf[65], *outbuf;
 
 	/* Can we find a top level raid set? */
-	top_idx = asr_find_toplevel(lc, asr);
-	if (top_idx < 0) {
+	if ((top_idx = find_toplevel(lc, asr)) < 0)
 		LOG_ERR(lc, NULL, "Can't find a FWL or FWL2 for FWP %x\n",
 			asr->rb.drivemagic);
-	}
-	top_set = find_set(lc, NULL, asr_name(lc, asr), FIND_TOP);
-	if (top_set != NULL) {
+
+	if (!(asr_name = name(lc, asr)))
+		return NULL;
+
+	if ((top_set = find_set(lc, NULL, asr_name, FIND_TOP))) {
 		if (asr->rt.ent[top_idx].raidlevel == FWL_2) {
 			/* double-layered; find the appropriate set */
 			list_for_each_entry(tmp, &top_set->sets, list) {
 				/* find the FWL that goes with the drive. */
-				fwl = asr_find_logical(asr);
-				if (fwl == NULL) {
+				if (!(fwl = find_logical(asr)))
 					LOG_ERR(lc, NULL,
 					"Can't find a FWL to go with FWP %x\n",
 					asr->rb.drivemagic);
-				}
-				snprintf(inbuf, 64, "asr_%s_%x", fwl->name,
-					fwl->raidmagic);
-				if (strcmp(tmp->name, inbuf) == 0) {
+
+				snprintf(inbuf, BUF_SIZE, "%s_%s_%x",
+					 HANDLER, fwl->name, fwl->raidmagic);
+
+				if (!strcmp(tmp->name, inbuf)) {
 					set = tmp;
 					break;
 				}
 			}
-		} else {
+		} else
 			set = top_set;
-		}
 
 		/* now attach it */
-		if (!set) {
+		if (!set)
 			LOG_ERR(lc, NULL, "No FWL to go with FWP %x\n",
 				asr->rb.drivemagic);
-		}
-		list_add_sorted(lc, &set->devs, &rd->devs, asr_dev_sort);
+
+		list_add_sorted(lc, &set->devs, &rd->devs, dev_sort);
 
 		return top_set;
 	}
@@ -533,73 +528,83 @@
 
 	/* If we're dealing with a single-level array... */
 	if (asr->rt.ent[top_idx].raidlevel == FWL) {
-		top_set = find_or_alloc_raid_set(lc, asr_name(lc, asr),
-			FIND_TOP, rd, LC_RS(lc), NO_CREATE, NO_CREATE_ARG);
+		if (!(top_set = find_or_alloc_raid_set(lc, asr_name,
+						       FIND_TOP, rd, LC_RS(lc),
+						       NO_CREATE,
+						       NO_CREATE_ARG))) {
+			log_err(lc, "Failed to create RAID set \"%s\"",
+				asr_name);
+			goto free;
+		}
 
-		top_set->stride = (cl ? cl->strpsize: 0);
+		top_set->stride = cl ? cl->strpsize: 0;
 		top_set->status = s_ok;
-		top_set->type = asr_type(asr_find_logical(asr));
+		top_set->type = type(find_logical(asr));
 
 		/* Add the disk to the set. */
-		list_add_sorted(lc, &top_set->devs, &rd->devs, asr_dev_sort);
+		list_add_sorted(lc, &top_set->devs, &rd->devs, dev_sort);
 		
 		return top_set;
 	}
 
 	/* Nope.  Two-level array. */
-	top_set = find_or_alloc_raid_set(lc, asr_name(lc, asr),
-		FIND_TOP, rd, LC_RS(lc), NO_CREATE, NO_CREATE_ARG);
-	top_set->stride = (cl ? cl->strpsize : 0);
+	if (!(top_set = find_or_alloc_raid_set(lc, asr_name, FIND_TOP,
+					       rd, LC_RS(lc), NO_CREATE,
+					       NO_CREATE_ARG))) {
+		log_err(lc, "Failed to create super set \"%s\"", asr_name);
+		goto free;
+	}
+
+	top_set->stride = cl ? cl->strpsize : 0;
 	top_set->status = s_ok;
-	top_set->type = asr_type(&asr->rt.ent[top_idx]);
+	top_set->type = type(&asr->rt.ent[top_idx]);
 
 	/* Find all FWLs that go with this FWL2 and add them. */
 	for (i = 0; i < asr->rt.elmcnt; i++) {
-		if (asr->rt.ent[i].raidlevel != FWL)
-			continue;
-		if (asr->rt.ent[i].raidcnt == 0)
+		if (asr->rt.ent[i].raidlevel != FWL ||
+		    !asr->rt.ent[i].raidcnt)
 			continue;
 
-		outbuf = malloc(32);
-		if (outbuf == NULL) {
+		if (!(outbuf = dbg_malloc(BUF_SIZE)))
 			LOG_ERR(lc, NULL, "Can't allocate array name.\n");
-		}
-		snprintf(outbuf, 64, "asr_%s_%x", asr->rt.ent[i].name,
-			asr->rt.ent[i].raidmagic);
-		set = alloc_raid_set(lc, __func__);
-		if (!set) {
-			LOG_ERR(lc, NULL, "Can't allocate RAID set.\n");
+
+		snprintf(outbuf, BUF_SIZE, "%s_%s_%x", HANDLER,
+			 asr->rt.ent[i].name, asr->rt.ent[i].raidmagic);
+
+		if (!(set = alloc_raid_set(lc, __func__))) {
+			log_err(lc, "Can't allocate RAID set.\n");
+			dbg_free(outbuf);
+
+			return NULL;
 		}
 
 		set->name = outbuf;
 		set->status = s_ok;
-		set->type = asr_type(asr_find_logical(asr));
-		list_add_sorted(lc, &top_set->sets, &set->list, no_sort);
+		set->type = type(find_logical(asr));
+		list_add_sorted(lc, &top_set->sets, &set->list, set_sort);
 
 		/* Add the drive to the set too */
-		fwl = asr_find_logical(asr);
-		if (fwl == NULL) {
+		if (!(fwl = find_logical(asr)))
 			LOG_ERR(lc, NULL,
 				"Can't find a FWL to go with FWP %x\n",
 				asr->rb.drivemagic);
-		}
-		if (fwl->raidmagic == asr->rt.ent[i].raidmagic) {
-			list_add_sorted(lc, &set->devs, &rd->devs, asr_dev_sort);
-		}
 
+		if (fwl->raidmagic == asr->rt.ent[i].raidmagic)
+			list_add_sorted(lc, &set->devs, &rd->devs, dev_sort);
 	}
 
-	printf("finished!\n");
-
 	return set;
+
+   free:
+	dbg_free(asr_name);
+
+	return NULL;
 }
 
 /* Write metadata. */
-static int asr_write(struct lib_context *lc,
-			  struct raid_dev *rd, int erase)
+static int asr_write(struct lib_context *lc, struct raid_dev *rd, int erase)
 {
-	fprintf(stderr, "ERROR: asr_write not implemented!\n");
-	return EPERM;
+	LOG_ERR(lc, EPERM, "ERROR: %s not yet implemented!", __func__);
 }
 
 #if 0
@@ -625,27 +630,27 @@
  */
 
 /* Retrieve the number of devices that should be in this set. */
-static unsigned int asr_device_count(struct raid_dev *rd, void *context)
+static unsigned int device_count(struct raid_dev *rd, void *context)
 {
 	/* Get the logical drive */
-	struct asr_raid_configline *cl = asr_find_logical(META(rd, asr));
+	struct asr_raid_configline *cl = find_logical(META(rd, asr));
+
 	return (cl ? cl->raidcnt : 0);
 }
 
 /* Check a RAID device */
-static int asr_check_rd(struct lib_context *lc, struct raid_set *rs,
+static int check_rd(struct lib_context *lc, struct raid_set *rs,
 		    struct raid_dev *rd, void *context)
 {
-	/* XXX: Assume non-broken means ok. */
+	/* FIXME: Assume non-broken means ok. */
 	return (rd->type != s_broken);
 }
 
 /* Start the recursive RAID set check. */
 static int asr_check(struct lib_context *lc, struct raid_set *rs)
 {
-	int f = check_raid_set(lc, rs, asr_device_count, NULL, asr_check_rd,
-		NULL, handler);
-	return f;
+	return check_raid_set(lc, rs, device_count, NULL,
+			      check_rd, NULL, handler);
 }
 
 /*
@@ -662,7 +667,7 @@
 };
 
 /* Dump a reserved block */
-static void asr_dump_rb(struct lib_context *lc, struct asr_reservedblock *rb)
+static void dump_rb(struct lib_context *lc, struct asr_reservedblock *rb)
 {
 	log_print(lc, "block magic:\t\t0x%X", rb->b0idcode);
 	log_print(lc, "sb0flags:\t\t0x%X", rb->sb0flags);
@@ -677,7 +682,7 @@
 }
 
 /* Dump a raid config line */
-static void asr_dump_cl(struct lib_context *lc, struct asr_raid_configline *cl)
+static void dump_cl(struct lib_context *lc, struct asr_raid_configline *cl)
 {
 	log_print(lc, "config ID:\t\t0x%X", cl->raidmagic);
 	log_print(lc, "  name:\t\t\t\"%s\"", cl->name);
@@ -695,7 +700,7 @@
 	log_print(lc, "  offset:\t\t%d", cl->loffset);
 	log_print(lc, "  capacity:\t\t%d", cl->lcapcty);
 	log_print(lc, "  stripe size:\t\t%d KB",
-		cl->strpsize * ASR_DISK_BLOCK_SIZE / 1024);
+		  cl->strpsize * ASR_DISK_BLOCK_SIZE / 1024);
 	log_print(lc, "  BIOS info:\t\t%d", cl->biosInfo);
 	log_print(lc, "  phys/log lun:\t\t%d", cl->lsu);
 	log_print(lc, "  addedDrives:\t\t%d", cl->addedDrives);
@@ -706,9 +711,10 @@
 }
 
 /* Dump a raid config table */
-static void asr_dump_rt(struct lib_context *lc, struct asr_raidtable *rt)
+static void dump_rt(struct lib_context *lc, struct asr_raidtable *rt)
 {
 	unsigned int i;
+
 	log_print(lc, "ridcode:\t\t0x%X", rt->ridcode);
 	log_print(lc, "table ver:\t\t%d", rt->rversion);
 	log_print(lc, "max configs:\t\t%d", rt->maxelm);
@@ -718,7 +724,7 @@
 	log_print(lc, "raid flags:\t\t0x%X", rt->raidFlags);
 	log_print(lc, "timestamp:\t\t0x%X", rt->timestamp);
 	log_print(lc, "irocFlags:\t\t0x%X%s", rt->irocFlags,
-		(rt->irocFlags & ASR_IF_BOOTABLE ? " (bootable)" : ""));
+		  (rt->irocFlags & ASR_IF_BOOTABLE ? " (bootable)" : ""));
 	log_print(lc, "dirty:\t\t\t%d", rt->dirty);
 	log_print(lc, "action prio:\t\t%d", rt->actionPriority);
 	log_print(lc, "spareid:\t\t%d", rt->spareid);
@@ -727,9 +733,9 @@
 	log_print(lc, "verifydate:\t\t0x%X", rt->verifyDate);
 	log_print(lc, "recreatedate:\t\t0x%X", rt->recreateDate);
 	log_print(lc, "RAID config table:");
-	for (i = 0; i < rt->elmcnt; i++) {
-		asr_dump_cl(lc, &rt->ent[i]);
-	}
+
+	for (i = 0; i < rt->elmcnt; i++)
+		dump_cl(lc, rt->ent + i);
 }
 
 #ifdef DMRAID_NATIVE_LOG
@@ -741,15 +747,15 @@
 	struct asr *asr = META(rd, asr);
 
 	log_print(lc, "%s (%s):", rd->di->path, handler);
-	asr_dump_rb(lc, &asr->rb);
-	asr_dump_rt(lc, &asr->rt);
+	dump_rb(lc, &asr->rb);
+	dump_rt(lc, &asr->rt);
 }
 #endif
 
 static struct dmraid_format asr_format = {
 	.name	= HANDLER,
 	.descr	= "Adaptec HostRAID ASR",
-	.caps	= "0,1",
+	.caps	= "0,1,10",
 	.format = FMT_RAID,
 	.read	= asr_read,
 	.write	= asr_write, // FIXME
@@ -770,12 +776,12 @@
 /*
  * Set up a RAID device from what we've assembled out of the metadata.
  */
-static int asr_setup_rd(struct lib_context *lc, struct raid_dev *rd,
+static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
 		    struct dev_info *di, void *meta, union read_info *info)
 {
 	struct asr *asr = meta;
 	struct meta_areas *ma;
-	struct asr_raid_configline *cl = asr_this_disk(asr);
+	struct asr_raid_configline *cl = this_disk(asr);
 
 	if (!cl)
 		LOG_ERR(lc, 0, "%s: Could not find current disk!\n",
@@ -789,33 +795,29 @@
 	ma = rd->meta_areas;
 	ma->offset = ASR_CONFIGOFFSET >> 9;
 	ma->size = ASR_DISK_BLOCK_SIZE;
-	ma->area = (void *)asr;
+	ma->area = (void*) asr;
 
 	/* Second area: raid table. */
 	ma++;
 	ma->offset = asr->rb.raidtbl;
 	ma->size = ASR_DISK_BLOCK_SIZE;
-	ma->area = (void *)asr;
+	ma->area = (void*) asr;
 
 	/* Third area: raid config table. */
 	ma++;
 	ma->offset = asr->rb.raidtbl + 1;
 	ma->size = 15 * ASR_DISK_BLOCK_SIZE;
-	ma->area = (void *)asr;
+	ma->area = (void*) asr;
 
 	/* Now set up the rest of the metadata info */
         rd->di = di;
 	rd->fmt = &asr_format;
 
-	rd->status = asr_disk_status(cl);
-	rd->type   = asr_type(cl);
+	rd->status = disk_status(cl);
+	rd->type   = type(cl);
 
 	rd->offset = ASR_DATAOFFSET;
 	rd->sectors = cl->lcapcty;
 
-        if ((rd->name = asr_name(lc, asr))) {
-		return 1;
-	}
-
-	return 0;
+        return (rd->name = name(lc, asr)) ? 1 : 0;
 }


More information about the Ataraid-list mailing list