[Dmraid-debian-commits] [SCM] Maintenance of the dmraid package branch, lenny, updated. cd7661ebfd968c212485e05af22308fcf9bfe673

Giuseppe Iuculano giuseppe at iuculano.it
Fri Jan 23 22:42:59 UTC 2009


The following commit has been merged in the lenny branch:
commit cd7661ebfd968c212485e05af22308fcf9bfe673
Author: Giuseppe Iuculano <giuseppe at iuculano.it>
Date:   Fri Jan 23 23:16:11 2009 +0100

    Delete 1.0.0.rc14/lib/format/ddf/ddf1.c.orig

diff --git a/1.0.0.rc14/lib/format/ddf/ddf1.c.orig b/1.0.0.rc14/lib/format/ddf/ddf1.c.orig
deleted file mode 100644
index 2cccdfc..0000000
--- a/1.0.0.rc14/lib/format/ddf/ddf1.c.orig
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- * SNIA DDF1 v1.0 metadata format handler.
- *
- * Copyright (C) 2005-2006 IBM, All rights reserved.
- * Written by Darrick Wong <djwong at us.ibm.com>
- *
- * Copyright (C) 2006 Heinz Mauelshage, Red Hat GmbH
- *                    All rights reserved.
- *
- * See file LICENSE at the top of this source tree for license information.
- */
-
-#include <errno.h>
-
-#define	HANDLER	"ddf1"
-
-#include "internal.h"
-
-#define	FORMAT_HANDLER
-#include "ddf1.h"
-
-// #include "ddf1_crc.h"
-#include "ddf1_cvt.h"
-#include "ddf1_dump.h"
-
-static const char *handler = HANDLER;
-
-/* PCI IDs for Adaptec */
-#define PCI_VENDOR_ID_ADAPTEC		0x9004
-#define PCI_VENDOR_ID_ADAPTEC2		0x9005
-
-/* Find the beginning of all DDF metadata */
-static uint64_t find_ddf_beginning(struct ddf1 *ddf1)
-{
-	uint64_t start;
-	struct ddf1_header *h = &ddf1->anchor;
-
-	start = ddf1->anchor_offset;
-	if (h->primary_table_lba < start)
-		start = h->primary_table_lba;
-	if (h->secondary_table_lba < start)
-		start = h->secondary_table_lba;
-#ifdef WORKSPACE_IS_PART_OF_DDF
-	if (ddf1->primary->workspace_lba < start)
-		start = ddf1->primary->workspace_lba;
-#endif
-
-	return start;
-}
-
-/* Figure out what endian conversions we need */
-static void find_endian(struct lib_context *lc, struct ddf1 *ddf1)
-{
-	uint8_t *ptr = (uint8_t*) &ddf1->anchor.signature;
-
-	if (ptr[0] == 0xDE && ptr[1] == 0x11)
-		ddf1->disk_format = BIG_ENDIAN;
-	else if (ptr[0] == 0x11 && ptr[1] == 0xDE)
-		ddf1->disk_format = LITTLE_ENDIAN;
-	else {
-		log_error(lc, "Can't figure out endianness!");
-		ddf1->disk_format = 0;
-	}
-}
-
-/* Map DDF1 disk status to dmraid status */
-static enum status disk_status(struct ddf1_phys_drive *disk) {
-	struct {
-		uint8_t	flag;
-		enum status status;
-	} states[] = {
-		{ 0x72, s_broken },
-		{ 0x04, s_nosync },
-		{ 0x08, s_setup },
-		{ 0x01, s_ok },
-	}, *s = states;
-
-	if (disk) {
-		do {
-			if (disk->state & s->flag)
-				return s->status;
-		} while ((s++)->status != s_ok);
-	}
-
-	return s_undef;
-}
-
-/*
- * Compare two GUIDs.  For some reason, Adaptec sometimes writes 0xFFFFFFFF
- * as the last four bytes (ala DDF2) and sometimes writes real data.
- * For now we'll compare the first twenty and only the last four if
- * both GUIDs don't have 0xFFFFFFFF in bytes 20-23.  Gross.
- */
-static inline uint8_t _and(uint8_t *p)
-{
-	return p[20] & p[21] & p[22] & p[23];
-}
-
-static int guidcmp(uint8_t *one, uint8_t *two)
-{
-	int x = memcmp(one, two, DDF1_GUID_LENGTH - 4);
-
-	if (x)
-		return x;
-
-	return (_and(one) || _and(two)) ? 0 : memcmp(one + 20, two + 20, 4);
-}
-
-/* Find the physical drive data for a drive */
-static struct ddf1_phys_drive *get_phys_drive(struct ddf1 *ddf1, uint32_t ref)
-{
-	unsigned int i = ddf1->pd_header->max_drives;
-	struct ddf1_phys_drive *pd;
-
-	while (i--) {
-		pd = ddf1->pds + i;
-		if (pd->reference == ref)
-			return pd;
-	}
-
-	return NULL;
-}
-
-/* Find this drive's physical data */
-static inline struct ddf1_phys_drive *get_this_phys_drive(struct ddf1 *ddf1)
-{
-	return get_phys_drive(ddf1, ddf1->disk_data->reference);
-}
-
-/* Find the virtual drive that goes with this config record */
-static struct ddf1_virt_drive *get_virt_drive(struct ddf1 *ddf1,
-					      struct ddf1_config_record *cr)
-{
-	int i = ddf1->vd_header->num_drives;
-	struct ddf1_virt_drive *vd;
-
-	while (i--) {
-		vd = ddf1->vds + i;
-		if (!guidcmp(vd->guid, cr->guid))
-			return vd;
-	}
-
-	return NULL;
-}
-
-/*
- * Find the index of the VD config record given a physical drive and offset.
- */
-static int get_config_byoffset(struct ddf1 *ddf1, struct ddf1_phys_drive *pd,
-			       uint64_t offset)
-{
-	int cfgs = NUM_CONFIG_ENTRIES(ddf1), i;
-	uint32_t *cfg_drive_ids, j;
-	uint64_t *cfg_drive_offsets;
-	struct ddf1_config_record *cfg;
-
-	for (i = 0; i < cfgs; i++) {
-		cfg = CR(ddf1, i);
-		if (cfg->signature == DDF1_VD_CONFIG_REC) {
-			cfg_drive_ids = CR_IDS(ddf1, cfg);
-			cfg_drive_offsets = CR_OFF(ddf1, cfg);
-			for (j = 0; j < cfg->primary_element_count; j++) {
-				if (cfg_drive_ids[j] == pd->reference &&
-				    cfg_drive_offsets[j] == offset)
-					return i;
-			}
-		}
-	}
-
-	return -ENOENT;
-}
-
-/* Find the index of the nth VD config record for this physical drive. */
-static int get_config_index(struct ddf1 *ddf1, struct ddf1_phys_drive *pd,
-			    unsigned int *n)
-{
-	int cfgs = NUM_CONFIG_ENTRIES(ddf1), i, j, nn = *n;
-	uint32_t *ids;
-	struct ddf1_config_record *cr;
-
-	for (i = 0; i < cfgs; i++) {
-		cr = CR(ddf1, i);
-		if (cr->signature == DDF1_VD_CONFIG_REC) {
-			ids = CR_IDS(ddf1, cr);
-			for (j = 0; j < cr->primary_element_count; j++) {
-				if (ids[j] == pd->reference && !nn--)
-						return i;
-			}
-		}
-	}
-
-	*n -= nn;
-	return nn < 0 ? -ENOENT : 0;
-}
-
-/*
- * Find the nth VD config record for this physical drive.
- */
-static inline struct ddf1_config_record *get_config(struct ddf1 *ddf1,
-						    struct ddf1_phys_drive *pd,
-						    unsigned int n)
-{
-	int i = get_config_index(ddf1, pd, &n);
-
-	return i < 0 ? NULL : CR(ddf1, i);
-}
- 
-/* Find a config record for this drive, given the offset of the array. */
-static inline struct ddf1_config_record *get_this_config(struct ddf1 *ddf1,
-							 uint64_t offset)
-{
-	struct ddf1_phys_drive *pd = get_this_phys_drive(ddf1);
-	int i = get_config_byoffset(ddf1, pd, offset);
-
-	return i < 0 ? NULL : get_config(ddf1, pd, i);
-}
-
-/* Find the config record disk/offset entry for this config/drive. */
-static int get_offset_entry(struct ddf1 *ddf1, struct ddf1_config_record *cr,
-			    struct ddf1_phys_drive *pd)
-{
-	int i;
-	uint32_t *ids;
-
-	if (cr) {
-		ids = CR_IDS(ddf1, cr);
-		for (i = 0; i < ddf1->primary->max_phys_drives; i++) {
-			if (ids[i] == pd->reference)
-				return i;
-		}
-	}
-
-	return -ENOENT;
-}
-
-/* Find the offset for this config/drive. */
-static uint64_t get_offset(struct ddf1 *ddf1, struct ddf1_config_record *cr,
-			   struct ddf1_phys_drive *pd)
-{
-	int i = get_offset_entry(ddf1, cr, pd);
-
-	return i < 0 ? pd->size : CR_OFF(ddf1, cr)[i];
-}
-
-/* Calculate the stripe size, in sectors */
-static inline unsigned int stride(struct ddf1_config_record *cr)
-{
-	return 1 << cr->stripe_size; // * 512 * 2;
-}
-
-/* Mapping of template types to generic types */
-static struct types types[] = {
-	{ DDF1_RAID0,	t_raid0 },
-	{ DDF1_RAID1,	t_raid1 },
-	{ DDF1_RAID4,	t_raid4 },
-	{ DDF1_CONCAT,	t_linear },
-	{ DDF1_JBOD,	t_linear },
-	{ 0, t_undef}
-};
-
-/* Seperate array for RAID5 qualifiers */
-static struct types qualifier_types[] = {
-	/* FIXME: Is RLQ=0 really right symmetric? */
-	{ DDF1_RAID5_RS, t_raid5_rs },
-	{ DDF1_RAID5_LA, t_raid5_la },
-	{ DDF1_RAID5_LS, t_raid5_ls },
-	{ 0, t_undef}
-};
-
-/* Map the DDF1 raid type codes into dmraid type codes. */
-static enum type type(struct lib_context *lc, struct ddf1 *ddf1,
-		      struct ddf1_config_record *cr)
-{
-	unsigned int l;
-	struct types *t;
-
-	if (!cr)
-		return t_undef;
-
-	l = cr->raid_level;
-	if (l == DDF1_RAID5) {
-		/*
-		 * FIXME: Do _all_ Adaptec controllers use left
-		 * asymmetric parity and write zero to RLQ?
-		 */
-		if (ddf1->adaptec_mode)
-			return t_raid5_la;
-
-		l = cr->raid_qualifier;
-		t = qualifier_types;
-	} else
-		t = types;
-
-	return rd_type(t, l);
-}
-
-/* Read the whole metadata chunk at once */
-static uint8_t *read_metadata_chunk(struct lib_context *lc, struct dev_info *di,
-				    uint64_t start)
-{
-	uint8_t *ret;
-	size_t size = (di->sectors - start) * DDF1_BLKSIZE;
-
-	if (!(ret = dbg_malloc(size)))
-		LOG_ERR(lc, ret, "%s: unable to allocate memory.", di->path);
-
-	if (!read_file(lc, handler, di->path, ret, size,
-		       start * DDF1_BLKSIZE)) {
-		dbg_free(ret);
-		LOG_ERR(lc, NULL, "%s: unable to read metadata.", di->path);
-	}
-
-	return ret;
-}
-
-static inline void cond_free(void *p)
-{
-	if (p)
-		dbg_free(p);
-}
-
-/*
- * Read an DDF1 RAID device.  Fields are little endian, so
- * need to convert them if we're on a BE machine (ppc, etc).
- */
-static int read_extended(struct lib_context *lc, struct dev_info *di,
-			 struct ddf1 *ddf1)
-{
-	int i;
-	uint64_t where;
-	size_t size;
-	struct ddf1_header *pri, *sec;
-	struct ddf1_adapter *adap;
-	struct ddf1_disk_data *ddata;
-	struct ddf1_phys_drives *pd;
-	struct ddf1_virt_drives *vd;
-
-	/* FIXME: We should verify the checksums... */
-
-	/* Read the primary DDF header */
-	where = ddf1->anchor.primary_table_lba * DDF1_BLKSIZE;
-	if (!(pri = ddf1->primary =
-	      alloc_private_and_read(lc, handler, sizeof(*pri),
-				     di->path, where)))
-		goto bad;
-
-	/* Read the secondary header. */
-	ddf1_cvt_header(ddf1, pri);
-	if (!(sec = ddf1->secondary = alloc_private(lc, handler, sizeof(*sec))))
-		goto bad;
-
-	where = ddf1->anchor.secondary_table_lba * DDF1_BLKSIZE;
-	if (ddf1->anchor.secondary_table_lba != 0xFFFFFFFFFFFFFFFFULL &&
-	    !read_file(lc, handler, di->path, sec, sizeof(*sec), where))
-		goto bad;
-
-	ddf1_cvt_header(ddf1, sec);
-	if (pri->signature != DDF1_HEADER) {
-		log_warn(lc, "%s: incorrect primary header signature %x",
-			 di->path, pri->signature);
-		cond_free(ddf1->primary);
-		ddf1->primary = NULL;
-	};
-	
-	if (sec->signature == DDF1_HEADER) {
-		/* If we encounter an error, we use the secondary table */
-		if (!ddf1->primary) {
-			log_warn(lc, "%s: using secondary header", di->path);
-			ddf1->primary = ddf1->secondary;
-			ddf1->secondary = NULL;
-		}
-	} else {
-		if (sec->signature)
-			log_warn(lc, "%s: bad secondary header signature %x",
-				 di->path, sec->signature);
-
-		dbg_free(sec);
-		ddf1->secondary = NULL;
-	}
-
-	if (!ddf1->primary) {
-		log_error(lc, "%s: both header signatures bad", di->path);
-		goto bad;
-	}
-
-	/* Read the adapter data */
-	if (!(adap = ddf1->adapter = alloc_private(lc, handler, sizeof(*adap))))
-		goto bad;
-
-	where = (pri->primary_table_lba + pri->adapter_data_offset)
-		* DDF1_BLKSIZE;
-	if (pri->adapter_data_offset != 0xFFFFFFFF &&
-	    !read_file(lc, handler, di->path, adap, sizeof(*adap), where))
-		goto bad;
-
-	ddf1_cvt_adapter(ddf1, ddf1->adapter);
-	if (ddf1->adapter->signature != DDF1_ADAPTER_DATA) {
-		if (ddf1->adapter->signature)
-			log_warn(lc, "%s: incorrect adapter data signature %x",
-				 di->path, ddf1->adapter->signature);
-		free (ddf1->adapter);
-		ddf1->adapter = NULL;
-	}
-
-	if (ddf1->adapter &&
-	    ddf1->adapter->pci_vendor == PCI_VENDOR_ID_ADAPTEC2)
-		ddf1->adaptec_mode = 1;
-
-	/* Read physical drive characteristic data */
-	where = (pri->primary_table_lba + pri->disk_data_offset) * DDF1_BLKSIZE;
-	if (!(ddata = ddf1->disk_data =
-	      alloc_private_and_read(lc, handler, sizeof(*ddata),
-				     di->path, where)))
-		goto bad;
-
-	/*
-	 * This table isn't technically required, but for now we rely
-	 * on it to give us a key into the physical drive table.
-	 */
-	ddf1_cvt_disk_data(ddf1, ddata);
-	if (ddata->signature != DDF1_FORCED_PD_GUID) {
-		log_warn(lc, "%s: incorrect disk data signature %x",
-			 di->path, ddata->signature);
-		goto bad;
-	}
-
-	/* Read physical drive data header */
-	where = (pri->primary_table_lba + pri->phys_drive_offset) *
-		DDF1_BLKSIZE;
-	size = pri->phys_drive_len * DDF1_BLKSIZE;
-	if (!(pd = ddf1->pd_header =
-	      alloc_private_and_read(lc, handler, size, di->path, where)))
-		goto bad;
-
-	ddf1_cvt_phys_drive_header(ddf1, pd);
-	if (pd->signature != DDF1_PHYS_DRIVE_REC) {
-		log_warn(lc, "%s: cannot find physical drive records",
-			 di->path);
-		goto bad;
-	}
-
-	/* Now read the physical drive data */
-	ddf1->pds = (struct ddf1_phys_drive *)(((uint8_t *)ddf1->pd_header) +
-		    sizeof (*pd));
-	for (i = 0; i < pd->num_drives; i++) {
-		ddf1_cvt_phys_drive(ddf1, &ddf1->pds[i]);
-		/*
-		 * Adaptec controllers have a weird bug where this field is
-		 * only four bytes ... and the next four are 0xFF.
-		 */
-		if (ddf1->pds[i].size >> 32 == 0xFFFFFFFF)
-			ddf1->pds[i].size &= 0xFFFFFFFF;
-	}
-
-	/* Read virtual drive data header */
-	where = (pri->primary_table_lba + pri->virt_drive_offset) *
-		DDF1_BLKSIZE;
-	size = pri->phys_drive_len * DDF1_BLKSIZE;
-	if (!(vd = ddf1->vd_header =
-	      alloc_private_and_read(lc, handler, size, di->path, where)))
-		goto bad;
-
-	ddf1_cvt_virt_drive_header(ddf1, vd);
-	if (vd->signature != DDF1_VIRT_DRIVE_REC) {
-		log_warn(lc, "%s: cannot find virtual drive records",
-			 di->path);
-		goto bad;
-	}
-
-	/* Now read the virtual drive data */
-	ddf1->vds = (struct ddf1_virt_drive*)(((uint8_t*) vd) + sizeof (*pd));
-	for (i = 0; i < vd->num_drives; i++)
-		ddf1_cvt_virt_drive(ddf1, &ddf1->vds[i]);
-
-	/* Read config data */
-	where = (pri->primary_table_lba + pri->config_record_offset) *
-		DDF1_BLKSIZE;
-	size = pri->config_record_len * DDF1_BLKSIZE;
-	if (!(ddf1->cfg = alloc_private_and_read(lc, handler, size,
-						 di->path, where)))
-		goto bad;
-
-	/*
-	 * Ensure each record is: a config table for VDs; a config table for
-	 * spare disks; or vendor-specifc data of some sort.
-	 */
-	ddf1_cvt_records(lc, di, ddf1, 1);
-
-	/*
-	 * FIXME: We don't pick up diagnostic logs, vendor specific logs,
-	 * bad block data, etc.  That shouldn't cause a problem with reading
-	 * or writing metadata, but at some point we might want to do something
-	 * with them.
-	 */
-	ddf1->in_cpu_format = 1;
-	return 1;
-
-bad:
-	ddf1->vds = NULL;
-	ddf1->pds = NULL;
-	cond_free(ddf1->cfg);
-	cond_free(ddf1->pd_header);
-	cond_free(ddf1->disk_data);
-	cond_free(ddf1->adapter);
-	cond_free(ddf1->secondary);
-	cond_free(ddf1->primary);
-	return 0;
-}
-
-
-/* Count the number of raid_devs we need to create for this drive */
-static unsigned int num_devs(struct lib_context *lc, void *meta)
-{
-	struct ddf1 *ddf1 = meta;
-	unsigned int num_drives = ~0;
-	
-	get_config_index(ddf1, get_this_phys_drive(ddf1), &num_drives);
-	return num_drives;
-}
-
-/* Check CRC on a given struct */
-/*
-enum struct_type { ANCHOR, HEADER_PRIM, HEADER_SEC,
-		   ADAPTER, DISK_DATA, PHYS_DRIVES,
-		   VIRT_DRIVES, CONFIG_RECORD };
-static uint32_t checksum(struct ddf1 *ddf1, enum struct_type type)
-{
-	struct {
-		enum struct_type type;
-		void *ptr;
-		size_t len;
-	} types[] = {
-		{ ANCHOR, &ddf1->anchor, sizeof(ddf1->anchor) },
-		{ HEADER_PRIM, ddf1->primary, sizeof(*ddf1->primary) },
-		{ HEADER_SEC, ddf1->secondary, sizeof(*ddf1->secondary) },
-		{ ADAPTER, ddf1->adapter, sizeof(*ddf1->adapter) },
-		{ DISK_DATA, ddf1->disk_data, sizeof(*ddf1->disk_data) },
-		{ PHYS_DRIVES, ddf1->pd_header, sizeof(*ddf1->pd_header) },
-		{ VIRT_DRIVES, ddf1->vd_header, sizeof(*ddf1->vd_header) },
-		{ CONFIG_RECORD, ddf1->cfg, sizeof(*ddf1->cfg) },
-	}, *t = ARRAY_END(types);
-
-	while (t-- > types) {
-		if (type == t->type)
-			return crc(t->ptr, t->len);
-	}
-
-	return 0;
-}
-*/
-
-/* Is this DDF1 metadata? */
-static inline int is_ddf1(struct lib_context *lc, struct dev_info *di,
-			  struct ddf1 *ddf1)
-{
-	/*
-	 * Check our magic numbers and that the version == v2.
-	 * We don't support anything other than that right now.
-	 */
-
-	/* FIXME: We should examine the version headers... */
-	return ddf1->anchor.signature == DDF1_HEADER ||
-	       ddf1->anchor.signature == DDF1_HEADER_BACKWARDS;
-}
-
-/* Try to find DDF1 metadata at a given offset (ddf1_sboffset) */
-static struct ddf1 *try_to_find_ddf1(struct lib_context *lc,
-				     struct dev_info *di,
-				     size_t *sz, uint64_t *offset,
-				     union read_info *info,
-				     uint64_t ddf1_sboffset)
-{
-	struct ddf1 *ddf1;
-	// uint32_t crc;
-
-	/*
-	 * Try to find a DDF1 anchor block at ddf1_sboffset.  In theory this
-	 * should be the very last block, but some Adaptec controllers have
-	 * issues with standards compliance.  So we have to try with various
-	 * offsets.
-	 */
-	if (!(ddf1 = alloc_private(lc, handler, sizeof(*ddf1))))
-		goto err;
-
-	if (!read_file(lc, handler, di->path, &ddf1->anchor, DDF1_BLKSIZE,
-		       ddf1_sboffset) ||
-	    !is_ddf1(lc, di, ddf1))
-		goto bad;
-
-	ddf1->anchor_offset = ddf1_sboffset;
-
-	/* Convert endianness */
-	ddf1->in_cpu_format = 0;
-	find_endian(lc, ddf1);
-	ddf1_cvt_header(ddf1, &ddf1->anchor);
-
-	/* FIXME: crc */
-/*
-	crc = checksum(ddf1, ANCHOR);
-	printf("crc=%08x ", crc);
-	printf("ddf1=%08x\n", ddf1->anchor.crc);
-*/
-
-	/* Read extended metadata. */
-	if (read_extended(lc, di, ddf1))
-		return ddf1;
-
-   bad:
-	dbg_free(ddf1);
-   err:
-	return NULL;
-}
-
-/*
- * Attempt to interpret DDF1 metadata from a block device.  This function
- * returns either NULL or a pointer to a descriptor struct.
- * Note that the struct should be fully converted to the correct endianness
- * by the time this function returns.
- */
-static void *read_metadata_areas(struct lib_context *lc, struct dev_info *di,
-				 size_t *sz, uint64_t *offset,
-				 union read_info *info)
-{
-	struct ddf1 *ddf1;
-
-	if ((ddf1 = try_to_find_ddf1(lc, di, sz, offset,
-				     info, DDF1_CONFIGOFFSET)))
-		goto out;
-
-	if ((ddf1 = try_to_find_ddf1(lc, di, sz, offset,
-				     info, DDF1_CONFIGOFFSET_ADAPTEC)))
-		ddf1->adaptec_mode = 1;
-
-   out:
-	return ddf1;
-}
-
-/* This is all hogwash since file_metadata can only be called once... */
-static void file_metadata_areas(struct lib_context *lc, struct dev_info *di,
-				void *meta)
-{
-	uint8_t *buf;
-	uint64_t start = find_ddf_beginning(meta);
-
-	if (!(buf = read_metadata_chunk(lc, di, start)))
-		return;
-
-	/* Record metadata. */
-	file_metadata(lc, handler, di->path, buf,
-		      (di->sectors - start) * DDF1_BLKSIZE,
-		      start * DDF1_BLKSIZE);
-
-	dbg_free(buf);
-
-	/* Record the device size. */
-	file_dev_size(lc, handler, di);
-}
-
-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 *ddf1_read(struct lib_context *lc,
-					struct dev_info *di)
-{
-	/*
-	 * 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, read_metadata_areas, 0, 0, NULL, NULL,
-			     file_metadata_areas, setup_rd, handler);
-}
-
-/* Compose an "identifier" for use as a sort key for raid sets. */
-static inline int compose_id(struct ddf1 *ddf1, struct raid_dev *rd)
-{
-	struct ddf1_phys_drive *pd = get_this_phys_drive(ddf1);
-	int i = get_config_byoffset(ddf1, pd, rd->offset);
-
-	return i < 0 ? -1 : get_offset_entry(ddf1, get_config(ddf1, pd, i), pd);
-}
-
-/* No sort. */
-static int no_sort(struct list_head *pos, struct list_head *new)
-{
-	return 0;
-}
-
-/* Sort DDF1 devices by for a RAID set. */
-static int dev_sort(struct list_head *pos, struct list_head *new)
-{
-	return compose_id(META(RD(new)->private.ptr, ddf1), RD(new)) <
-	       compose_id(META(RD(pos)->private.ptr, ddf1), RD(pos));
-}
-
-/*
- * IO error event handler.
- */
-static int event_io(struct lib_context *lc, struct event_io *e_io)
-{
-	log_err(lc, "I/O error on device %s at sector %lu.\n",
-		e_io->rd->di->path, e_io->sector);
-
-	LOG_ERR(lc, 0, "PANIC: ddf1 doesn't know about event_io!\n");
-}
-
-#if 0
-	/* FIXME: This should not use META() directly? */
-	struct raid_dev *rd = e_io->rd;
-	struct ddf1 *ddf1 = META(rd, ddf1);
-	struct ddf1_raid_configline *cl = this_disk(ddf1);
-	struct ddf1_raid_configline *fwl = find_logical(ddf1);
-
-	/* Ignore if we've already marked this disk broken(?) */
-	if (rd->status & s_broken)
-		return 0;
-	
-	/* Mark the array as degraded and the disk as failed. */
-	rd->status = s_broken;
-	cl->raidstate = LSU_COMPONENT_STATE_FAILED;
-	fwl->raidstate = LSU_COMPONENT_STATE_DEGRADED;
-	/* FIXME: Do we have to mark a parent too? */
-
-	/* Indicate that this is indeed a failure. */
-	return 1;
-}
-#endif
-
-#define NAME_SIZE 64
-/* Formulate a RAID set name for this disk. */
-static char *name(struct lib_context *lc, struct ddf1 *ddf1,
-		  struct raid_dev *rd)
-{
-	int i, prefix;
-	char *buf, *r;
-	struct ddf1_phys_drive *pd;
-	struct ddf1_virt_drive *vd;
-	struct ddf1_config_record *cr;
-
-	if (!(pd = get_this_phys_drive(ddf1)))
-		LOG_ERR(lc, NULL, "Cannot find physical drive description!");
-
-	if (!(buf = dbg_malloc(NAME_SIZE)))
-		LOG_ERR(lc, NULL, "Cannot allocate memory for name.");
-
-	i = get_config_byoffset(ddf1, pd, rd->offset);
- 	cr = get_config(ddf1, pd, i);
- 	if (i < 0 || !cr) {
-		sprintf(buf, ".ddf1_spares");
-		goto out;
-	}
-
-	if (!(vd = get_virt_drive(ddf1, cr))) {
-		dbg_free(buf);
-		LOG_ERR(lc, NULL, "Cannot find virtual drive description!");
-	}
-
-	sprintf(buf, "%s_", handler);
-	prefix = strlen(buf);
-
-	if (vd->name[0]) {
-		memcpy(buf + prefix, vd->name, 16);
-		i = prefix + 16;
-		while (!isgraph(buf[--i]));
-		buf[i+1] = 0;
-	} else {
-		char *b;
-
-		for (b = buf + prefix, i = 0; i < 24; b += 8, i += 4)
-			sprintf(b, "%02x%02x%02x%02x",
-				vd->guid[i], vd->guid[i+1],
-			        vd->guid[i+2], vd->guid[i+3]);
-	}
-
-   out:
-	/* Just return the needed allocation */
-	r = dbg_strdup(buf);
-	dbg_free(buf);
-
-	return r;
-}
-
-/* Figure out the real size of a disk... */
-static uint64_t get_size(struct lib_context *lc, struct ddf1 *ddf1,
-			 struct ddf1_config_record *cr,
-			 struct ddf1_phys_drive *pd)
-{
-	if (cr)
-		/* Some Adaptec controllers need this clamping. */
-		return type(lc, ddf1, cr) == t_raid0 ?
-		       cr->sectors - cr->sectors % stride(cr) : cr->sectors;
-
-	return pd->size;
-}
-
-/*
- * Create all the volumes of a DDF disk as subsets of the top level DDF
- * disk group.  rs_group points to that raid set and is returned if the
- * function is successful, NULL if not.  rd_group is the raid_dev that
- * represents the entire disk drive.
- */
-static struct raid_set *group_rd(struct lib_context *lc,
-				 struct raid_set *rs_group,
-				 struct raid_dev *rd_group)
-{
-	struct ddf1 *ddf1 = META(rd_group, ddf1);
-	struct raid_set *rs = NULL;
-	struct raid_dev *rd;
-	struct ddf1_config_record *cr;
-	struct ddf1_phys_drive *pd;
-	unsigned int devs, i;
-	
-	if (!(pd = get_this_phys_drive(ddf1)))
-		return NULL;
-
-	devs = num_devs(lc, ddf1);
-	for (i = 0; i < devs; i++) {
-		/* Allocate a raid_dev for this volume */
-		if (!(rd = alloc_raid_dev(lc, handler)))
-			return NULL;
-
-		cr = get_config(ddf1, pd, i);
-		rd->di = rd_group->di;
-		rd->fmt = rd_group->fmt;
-		rd->type = type(lc, ddf1, cr);
-		rd->offset = get_offset(ddf1, cr, pd);
-		rd->sectors = get_size(lc, ddf1, cr, pd);
-		rd->name = name(lc, ddf1, rd);
-
-		/* Stuff it into the appropriate raid set. */
-		if (!(rs = find_or_alloc_raid_set(lc, rd->name, FIND_ALL,
-						  rd, &rs_group->sets,
-						  NO_CREATE, NO_CREATE_ARG))) {
-			free_raid_dev(lc, &rd);
-			return NULL;
-		}
-
-		rs->stride = stride(cr);
-		rs->type = type(lc, ddf1, cr);
-		rs->status = s_ok;
-
-		if (!(rd->private.ptr = alloc_private(lc, handler,
-						      sizeof(*rd_group))))
-			return NULL;
-
-		memcpy(rd->private.ptr, rd_group, sizeof (*rd_group));
-		list_add_sorted(lc, &rs->devs, &rd->devs, dev_sort);
-	}
-
-	return rs_group;
-}
-
-/* 
- * Add an DDF1 device to a RAID set.  This involves finding the raid set to
- * which this disk belongs, and then attaching it.  Note that there are other
- * complications, such as two-layer arrays (RAID10).
- *
- * FIXME: We haven't been able to set up a RAID10 for testing...
- */
-static struct raid_set *ddf1_group(struct lib_context *lc, struct raid_dev *rd)
-{
-	struct ddf1 *ddf1 = META(rd, ddf1);
-	struct ddf1_phys_drive *pd;
-	struct raid_set *rs;
-	char *set_name;
-
-	if (!(pd = get_this_phys_drive(ddf1)))
-		LOG_ERR(lc, NULL, "Cannot find physical drive description!\n");
-
-	if (!(set_name = rd->name))
-		LOG_ERR(lc, NULL, "%s: Could not find RAID array name.\n",
-			rd->di->path);
-
-	/*
-	 * Find/create a raid set for all DDF drives and put this disk
-	 * into that set.  The raid_sets for the real arrays will be created
-	 * as children of the disk's raid_set.
-	 *
-	 * (Is this really necessary?)
-	 */
-	if (!(rs = find_or_alloc_raid_set(lc, set_name, FIND_TOP, rd,
-					  LC_RS(lc), NO_CREATE,
-					  NO_CREATE_ARG)))
-		return NULL;
-
-	rs->type = t_group;
-	list_add_sorted(lc, &rs->devs, &rd->devs, no_sort);
-
-	/* Go deal with the real arrays. */
-	return group_rd(lc, rs, rd);
-}
-
-/* Write metadata. */
-static int ddf1_write(struct lib_context *lc,  struct raid_dev *rd, int erase)
-{
-	int ret;
-        struct ddf1 *ddf1 = META(rd, ddf1);
-
-        ddf1_cvt_all(lc, ddf1, rd->di);
-        ret = write_metadata(lc, handler, rd, -1, erase);
-        ddf1_cvt_all(lc, ddf1, rd->di);
-
-        return ret;
-}
-
-/*
- * Check integrity of a RAID set.
- */
-
-/* Retrieve the number of devices that should be in this set. */
-static unsigned int device_count(struct raid_dev *rd, void *context)
-{
-	/* Get the logical drive */
-	struct ddf1_config_record *cr =
-		get_this_config(META(rd->private.ptr, ddf1), rd->offset);
-
-	return cr ? cr->primary_element_count : 0;
-}
-
-/* Check a RAID device */
-static int check_rd(struct lib_context *lc, struct raid_set *rs,
-		    struct raid_dev *rd, void *context)
-{
-	/*
-	 * FIXME: Should we do more checking for brokenness here?
-	 * We could check SMART data, verify that nobody else is
-	 * putting non-ddf disks in our raid set, etc.
-	 */
-	return rd->type != s_broken;
-}
-
-/* Start the recursive RAID set check. */
-static int ddf1_check(struct lib_context *lc, struct raid_set *rs)
-{
-	return check_raid_set(lc, rs, device_count, NULL, check_rd,
-			      NULL, handler);
-}
-
-static struct event_handlers ddf1_event_handlers = {
-	.io = event_io,
-	.rd = NULL,	/* FIXME: no device add/remove event handler yet. */
-};
-
-#ifdef DMRAID_NATIVE_LOG
-/*
- * Log native information about the RAID device.
- */
-static void ddf1_log(struct lib_context *lc, struct raid_dev *rd)
-{
-	ddf1_dump_all(lc, handler, META(rd, ddf1), rd->di);
-}
-#endif /* #ifdef DMRAID_NATIVE_LOG  */
-
-static struct dmraid_format ddf1_format = {
-	.name	= HANDLER,
-	.descr	= "SNIA DDF1",
-	.caps	= "0,1,4,5,linear",
-	.format = FMT_RAID,
-	.read	= ddf1_read,
-	.write	= ddf1_write,
-	.group	= ddf1_group,
-	.check	= ddf1_check,
-	.events	= &ddf1_event_handlers,
-#ifdef DMRAID_NATIVE_LOG
-	.log	= ddf1_log,
-#endif
-};
-
-/* Register this format handler with the format core */
-int register_ddf1(struct lib_context *lc)
-{
-	return register_format_handler(lc, &ddf1_format);
-}
-
-/*
- * Set up a RAID device from what we've assembled out of the metadata.
- */
-static int setup_rd(struct lib_context *lc, struct raid_dev *rd,
-		    struct dev_info *di, void *meta, union read_info *info)
-{
-	unsigned int i, ma_count = 5;
-	struct ddf1 *ddf1 = meta;
-	struct meta_areas *ma;
-	struct ddf1_phys_drive *pd;
-
-	if (!(pd = get_this_phys_drive(ddf1)))
-		LOG_ERR(lc, 0, "Cannot find physical drive description!\n");
-
-	/* We need multiple metadata areas */
-	ma_count += ddf1->adapter ? 1 : 0;
-	ma_count += ddf1->secondary ? 1 : 0;
-	ma_count += ddf1->disk_data ? 1 : 0;
-	/* FIXME: metadata area for workspace_lba */
-
-	if (!(ma = rd->meta_areas = alloc_meta_areas(lc, rd, handler,
-						     ma_count)))
-		return 0;
-
-	/* Preset metadata area offset and size and adjust below */
-	for (i = 0; i < ma_count; i++) {
-		ma[i].offset = ddf1->primary->primary_table_lba;
-		ma[i].size = DDF1_BLKSIZE;
-	}
-
-	ma->offset = ddf1->anchor_offset;
-	(ma++)->area = &ddf1->anchor;
-
-	(ma++)->area = ddf1->primary;
-
-	if (ddf1->secondary)
-		(ma++)->offset = ddf1->primary->secondary_table_lba;
-
-	if (ddf1->adapter) {
-		ma->offset += ddf1->primary->adapter_data_offset;
-		ma->size *= ddf1->primary->adapter_data_len;
-		(ma++)->area = ddf1->adapter;
-	}
-
-	/* FIXME: set up workspace_lba */
-
-	if (ddf1->disk_data) {
-		ma->offset += ddf1->primary->disk_data_offset;
-		ma->size *= ddf1->primary->disk_data_len;
-		(ma++)->area = ddf1->disk_data;
-	}
-
-	ma->offset += ddf1->primary->phys_drive_offset;
-	ma->size *= ddf1->primary->phys_drive_len;
-	(ma++)->area = ddf1->pd_header;
-
-	ma->offset += ddf1->primary->virt_drive_offset;
-	ma->size *= ddf1->primary->virt_drive_len;
-	(ma++)->area = ddf1->vd_header;
-
-	ma->offset += ddf1->primary->config_record_offset;
-	ma->size *= ddf1->primary->config_record_len;
-	ma->area = ddf1->cfg;
-
-	/* Now set up the rest of the metadata info */
-        rd->di = di;
-	rd->fmt = &ddf1_format;
-	rd->status = disk_status(pd);
-	rd->type = t_group;
-	rd->offset = 0;
-	rd->sectors = get_size(lc, ddf1, NULL, pd);
-	rd->name = dbg_strdup((char*) ".ddf_disks"); /* FIXME: better name */
-	return rd->name ? 1 : 0;
-}

-- 
Maintenance of the dmraid package



More information about the Dmraid-debian-commits mailing list