[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