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@xxxxxxxxxx > 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@xxxxxxxxxx +49 2626 141200 FAX 924446 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--- 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; }
_______________________________________________ Ataraid-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/ataraid-list