Date: Tue, 22 Mar 2011 20:00:27 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r219881 - projects/graid/head/sys/geom/raid Message-ID: <201103222000.p2MK0Rpq069638@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Tue Mar 22 20:00:27 2011 New Revision: 219881 URL: http://svn.freebsd.org/changeset/base/219881 Log: Add basic NVidia metadata write support. Modified: projects/graid/head/sys/geom/raid/md_nvidia.c Modified: projects/graid/head/sys/geom/raid/md_nvidia.c ============================================================================== --- projects/graid/head/sys/geom/raid/md_nvidia.c Tue Mar 22 19:52:29 2011 (r219880) +++ projects/graid/head/sys/geom/raid/md_nvidia.c Tue Mar 22 20:00:27 2011 (r219881) @@ -57,37 +57,43 @@ struct nvidia_raid_conf { uint32_t sector_size; uint8_t name[16]; uint8_t revision[4]; - uint32_t dummy_1; + uint32_t disk_status; uint32_t magic_0; -#define NVIDIA_MAGIC0 0x00640044 +#define NVIDIA_MAGIC0 0x00640044 uint64_t volume_id[2]; - uint8_t flags; + uint8_t state; +#define NVIDIA_S_IDLE 0 +#define NVIDIA_S_INIT 2 +#define NVIDIA_S_REBUILD 3 +#define NVIDIA_S_UPGRADE 4 +#define NVIDIA_S_SYNC 5 uint8_t array_width; uint8_t total_disks; - uint8_t dummy_2; + uint8_t orig_array_width; uint16_t type; -#define NVIDIA_T_RAID0 0x00000080 -#define NVIDIA_T_RAID1 0x00000081 -#define NVIDIA_T_RAID3 0x00000083 -#define NVIDIA_T_RAID5 0x00000085 -#define NVIDIA_T_RAID10 0x00008180 -#define NVIDIA_T_CONCAT 0x000000ff +#define NVIDIA_T_RAID0 0x0080 +#define NVIDIA_T_RAID1 0x0081 +#define NVIDIA_T_RAID3 0x0083 +#define NVIDIA_T_RAID5 0x0085 /* RLQ = 00/02? */ +#define NVIDIA_T_RAID5_SYM 0x0095 /* RLQ = 03 */ +#define NVIDIA_T_RAID10 0x8180 +#define NVIDIA_T_CONCAT 0x00ff uint16_t dummy_3; uint32_t strip_sectors; uint32_t strip_bytes; uint32_t strip_shift; uint32_t strip_mask; - uint32_t strip_sizesectors; - uint32_t strip_sizebytes; + uint32_t stripe_sectors; + uint32_t stripe_bytes; uint32_t rebuild_lba; uint32_t orig_type; uint32_t orig_total_sectors; uint32_t status; -#define NVIDIA_S_BOOTABLE 0x00000001 -#define NVIDIA_S_DEGRADED 0x00000002 +#define NVIDIA_S_BOOTABLE 0x00000001 +#define NVIDIA_S_DEGRADED 0x00000002 uint32_t filler[98]; } __packed; @@ -149,7 +155,7 @@ g_raid_md_nvidia_print(struct nvidia_rai printf("********* ATA NVidia RAID Metadata *********\n"); printf("nvidia_id <%.8s>\n", meta->nvidia_id); - printf("config_size 0x%08x\n", meta->config_size); + printf("config_size %u\n", meta->config_size); printf("checksum 0x%08x\n", meta->checksum); printf("version 0x%04x\n", meta->version); printf("disk_number %d\n", meta->disk_number); @@ -160,22 +166,22 @@ g_raid_md_nvidia_print(struct nvidia_rai printf("revision 0x%02x%02x%02x%02x\n", meta->revision[0], meta->revision[1], meta->revision[2], meta->revision[3]); - printf("dummy_1 0x%08x\n", meta->dummy_1); + printf("disk_status 0x%08x\n", meta->disk_status); printf("magic_0 0x%08x\n", meta->magic_0); printf("volume_id 0x%016jx%016jx\n", - meta->volume_id[0], meta->volume_id[1]); - printf("flags 0x%02x\n", meta->flags); + meta->volume_id[1], meta->volume_id[0]); + printf("state 0x%02x\n", meta->state); printf("array_width %u\n", meta->array_width); printf("total_disks %u\n", meta->total_disks); - printf("dummy_2 0x%02x\n", meta->dummy_2); + printf("orig_array_width %u\n", meta->orig_array_width); printf("type 0x%04x\n", meta->type); printf("dummy_3 0x%04x\n", meta->dummy_3); printf("strip_sectors %u\n", meta->strip_sectors); printf("strip_bytes %u\n", meta->strip_bytes); printf("strip_shift %u\n", meta->strip_shift); printf("strip_mask 0x%08x\n", meta->strip_mask); - printf("strip_sizesectors %u\n", meta->strip_sizesectors); - printf("strip_sizebytes %u\n", meta->strip_sizebytes); + printf("stripe_sectors %u\n", meta->stripe_sectors); + printf("stripe_bytes %u\n", meta->stripe_bytes); printf("rebuild_lba %u\n", meta->rebuild_lba); printf("orig_type 0x%04x\n", meta->orig_type); printf("orig_total_sectors %u\n", meta->orig_total_sectors); @@ -207,7 +213,6 @@ nvidia_meta_get_name(struct nvidia_raid_ } } -#if 0 static void nvidia_meta_put_name(struct nvidia_raid_conf *meta, char *buf) { @@ -215,7 +220,6 @@ nvidia_meta_put_name(struct nvidia_raid_ memset(meta->name, 0x20, 16); memcpy(meta->name, buf, MIN(strlen(buf), 16)); } -#endif static struct nvidia_raid_conf * nvidia_meta_read(struct g_consumer *cp) @@ -274,6 +278,7 @@ nvidia_meta_read(struct g_consumer *cp) /* Check raid type. */ if (meta->type != NVIDIA_T_RAID0 && meta->type != NVIDIA_T_RAID1 && meta->type != NVIDIA_T_RAID3 && meta->type != NVIDIA_T_RAID5 && + meta->type != NVIDIA_T_RAID5_SYM && meta->type != NVIDIA_T_RAID10 && meta->type != NVIDIA_T_CONCAT) { G_RAID_DEBUG(1, "NVidia unknown RAID level on %s (0x%02x)", pp->name, meta->type); @@ -284,20 +289,20 @@ nvidia_meta_read(struct g_consumer *cp) return (meta); } -#if 0 static int nvidia_meta_write(struct g_consumer *cp, struct nvidia_raid_conf *meta) { struct g_provider *pp; char *buf; int error, i; - uint16_t checksum, *ptr; + uint32_t checksum, *ptr; pp = cp->provider; /* Recalculate checksum for case if metadata were changed. */ meta->checksum = 0; - for (checksum = 0, ptr = (uint16_t *)meta, i = 0; i < 159; i++) + for (checksum = 0, ptr = (uint32_t *)meta, + i = 0; i < meta->config_size; i++) checksum += *ptr++; meta->checksum -= checksum; @@ -305,41 +310,32 @@ nvidia_meta_write(struct g_consumer *cp, buf = malloc(pp->sectorsize, M_MD_NVIDIA, M_WAITOK | M_ZERO); memcpy(buf, meta, sizeof(*meta)); - /* Write 4 copies of metadata. */ - for (i = 0; i < 4; i++) { - error = g_write_data(cp, - pp->mediasize - (pp->sectorsize * (1 + 0x200 * i)), - buf, pp->sectorsize); - if (error != 0) { - G_RAID_DEBUG(1, "Cannot write metadata to %s (error=%d).", - pp->name, error); - break; - } + /* Write metadata. */ + error = g_write_data(cp, + pp->mediasize - 2 * pp->sectorsize, buf, pp->sectorsize); + if (error != 0) { + G_RAID_DEBUG(1, "Cannot write metadata to %s (error=%d).", + pp->name, error); } free(buf, M_MD_NVIDIA); return (error); } -#endif static int nvidia_meta_erase(struct g_consumer *cp) { struct g_provider *pp; char *buf; - int error, i; + int error; pp = cp->provider; buf = malloc(pp->sectorsize, M_MD_NVIDIA, M_WAITOK | M_ZERO); - /* Write 4 copies of metadata. */ - for (i = 0; i < 4; i++) { - error = g_write_data(cp, - pp->mediasize - (pp->sectorsize * (1 + 0x200 * i)), - buf, pp->sectorsize); - if (error != 0) { - G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).", - pp->name, error); - } + error = g_write_data(cp, + pp->mediasize - 2 * pp->sectorsize, buf, pp->sectorsize); + if (error != 0) { + G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).", + pp->name, error); } free(buf, M_MD_NVIDIA); return (error); @@ -692,6 +688,7 @@ g_raid_md_nvidia_start(struct g_raid_sof nvidia_meta_get_name(meta, buf); vol = g_raid_create_volume(sc, buf, -1); vol->v_mediasize = (off_t)meta->total_sectors * 512; + vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE; if (meta->type == NVIDIA_T_RAID0) { vol->v_raid_level = G_RAID_VOLUME_RL_RAID0; size = vol->v_mediasize / mdi->mdio_total_disks; @@ -710,11 +707,14 @@ g_raid_md_nvidia_start(struct g_raid_sof } else if (meta->type == NVIDIA_T_RAID5) { vol->v_raid_level = G_RAID_VOLUME_RL_RAID5; size = vol->v_mediasize / (mdi->mdio_total_disks - 1); + } else if (meta->type == NVIDIA_T_RAID5_SYM) { + vol->v_raid_level = G_RAID_VOLUME_RL_RAID5; +// vol->v_raid_level_qualifier = 0x03; + size = vol->v_mediasize / (mdi->mdio_total_disks - 1); } else { vol->v_raid_level = G_RAID_VOLUME_RL_UNKNOWN; size = 0; } - vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE; vol->v_strip_size = meta->strip_sectors * 512; //ZZZ vol->v_disks_count = mdi->mdio_total_disks; vol->v_sectorsize = 512; //ZZZ @@ -847,8 +847,8 @@ g_raid_md_create_nvidia(struct g_raid_md mdi = (struct g_raid_md_nvidia_object *)md; arc4rand(&mdi->mdio_volume_id, 16, 0); mdi->mdio_generation = 0; - snprintf(name, sizeof(name), "NVidia-%016jx%016jx", - mdi->mdio_volume_id[0], mdi->mdio_volume_id[1]); + snprintf(name, sizeof(name), "NVidia-%08x", + (uint32_t)mdi->mdio_volume_id[0]); sc = g_raid_create_node(mp, name, md); if (sc == NULL) return (G_RAID_MD_TASTE_FAIL); @@ -954,8 +954,8 @@ search: } else { /* Not found matching node -- create one. */ result = G_RAID_MD_TASTE_NEW; memcpy(&mdi->mdio_volume_id, &meta->volume_id, 16); - snprintf(name, sizeof(name), "NVidia-%016jx%016jx", - mdi->mdio_volume_id[0], mdi->mdio_volume_id[1]); + snprintf(name, sizeof(name), "NVidia-%08x", + (uint32_t)mdi->mdio_volume_id[0]); sc = g_raid_create_node(mp, name, md); md->mdo_softc = sc; geom = sc->sc_geom; @@ -1174,7 +1174,7 @@ g_raid_md_ctl_nvidia(struct g_raid_md_ob return (error); /* Reserve space for metadata. */ - size -= 0x800 * sectorsize; + size -= 2 * sectorsize; /* Handle size argument. */ len = sizeof(*sizearg); @@ -1447,7 +1447,6 @@ static int g_raid_md_write_nvidia(struct g_raid_md_object *md, struct g_raid_volume *tvol, struct g_raid_subdisk *tsd, struct g_raid_disk *tdisk) { -#if 0 struct g_raid_softc *sc; struct g_raid_volume *vol; struct g_raid_subdisk *sd; @@ -1464,7 +1463,7 @@ g_raid_md_write_nvidia(struct g_raid_md_ return (0); /* Bump generation. Newly written metadata may differ from previous. */ - mdi->mdio_generation++; +// mdi->mdio_generation++; /* There is only one volume. */ vol = TAILQ_FIRST(&sc->sc_volumes); @@ -1473,36 +1472,51 @@ g_raid_md_write_nvidia(struct g_raid_md_ meta = malloc(sizeof(*meta), M_MD_NVIDIA, M_WAITOK | M_ZERO); if (mdi->mdio_meta) memcpy(meta, mdi->mdio_meta, sizeof(*meta)); + memcpy(meta->nvidia_id, NVIDIA_MAGIC, sizeof(NVIDIA_MAGIC)); + meta->config_size = 30; + meta->version = 0x0064; meta->total_sectors = vol->v_mediasize / vol->v_sectorsize; - meta->vendor_id = 0x1095; - meta->version_minor = 0; - meta->version_major = 2; + meta->sector_size = vol->v_sectorsize; + nvidia_meta_put_name(meta, vol->v_name); + meta->magic_0 = NVIDIA_MAGIC0; memcpy(&meta->volume_id, &mdi->mdio_volume_id, 16); - meta->strip_sectors = vol->v_strip_size / vol->v_sectorsize; - if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID0) { + meta->state = NVIDIA_S_IDLE; + if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1) + meta->array_width = 1; + else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E) + meta->array_width = vol->v_disks_count / 2; + else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID5) + meta->array_width = vol->v_disks_count - 1; + else + meta->array_width = vol->v_disks_count; + meta->total_disks = vol->v_disks_count; + meta->orig_array_width = meta->array_width; + if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID0) meta->type = NVIDIA_T_RAID0; - meta->raid0_disks = vol->v_disks_count; - meta->raid1_disks = 0xff; - } else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1) { + else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1) meta->type = NVIDIA_T_RAID1; - meta->raid0_disks = 0xff; - meta->raid1_disks = vol->v_disks_count; - } else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E) { + else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E) meta->type = NVIDIA_T_RAID10; - meta->raid0_disks = vol->v_disks_count / 2; - meta->raid1_disks = 2; - } else if (vol->v_raid_level == G_RAID_VOLUME_RL_CONCAT || - vol->v_raid_level == G_RAID_VOLUME_RL_SINGLE) { + else if (vol->v_raid_level == G_RAID_VOLUME_RL_CONCAT || + vol->v_raid_level == G_RAID_VOLUME_RL_SINGLE) meta->type = NVIDIA_T_CONCAT; - meta->raid0_disks = vol->v_disks_count; - meta->raid1_disks = 0xff; - } else { - meta->type = NVIDIA_T_RAID5; - meta->raid0_disks = vol->v_disks_count; - meta->raid1_disks = 0xff; - } - meta->generation = mdi->mdio_generation; - meta->raid_status = vol->v_dirty ? NVIDIA_S_ONLINE : NVIDIA_S_AVAILABLE; +// else if (vol->v_raid_level_qualifier == 0) +// meta->type = NVIDIA_T_RAID5; + else + meta->type = NVIDIA_T_RAID5_SYM; + meta->strip_sectors = vol->v_strip_size / vol->v_sectorsize; + meta->strip_bytes = vol->v_strip_size; + meta->strip_shift = ffs(meta->strip_sectors) - 1; + meta->strip_mask = meta->strip_sectors - 1; + meta->stripe_sectors = meta->strip_sectors * meta->orig_array_width; + meta->stripe_bytes = meta->stripe_sectors * vol->v_sectorsize; + meta->rebuild_lba = 0; + meta->orig_type = meta->type; + meta->orig_total_sectors = meta->total_sectors; + meta->status = 0; + +// meta->generation = mdi->mdio_generation; +/* meta->raid_status = vol->v_dirty ? NVIDIA_S_ONLINE : NVIDIA_S_AVAILABLE; for (i = 0; i < vol->v_disks_count; i++) { sd = &vol->v_subdisks[i]; if (sd->sd_state == G_RAID_SUBDISK_S_STALE || @@ -1510,7 +1524,7 @@ g_raid_md_write_nvidia(struct g_raid_md_ meta->raid_status = NVIDIA_S_ONLINE; } meta->raid_location = mdi->mdio_location; - nvidia_meta_put_name(meta, vol->v_name); +*/ /* We are done. Print meta data and store them to disks. */ if (mdi->mdio_meta != NULL) @@ -1527,7 +1541,8 @@ g_raid_md_write_nvidia(struct g_raid_md_ } pd->pd_meta = nvidia_meta_copy(meta); if ((sd = TAILQ_FIRST(&disk->d_subdisks)) != NULL) { - if (sd->sd_state < G_RAID_SUBDISK_S_NEW) + pd->pd_meta->disk_number = sd->sd_pos; +/* if (sd->sd_state < G_RAID_SUBDISK_S_NEW) pd->pd_meta->disk_status = NVIDIA_S_DROPPED; else if (sd->sd_state < G_RAID_SUBDISK_S_STALE) { pd->pd_meta->disk_status = NVIDIA_S_REBUILD; @@ -1535,26 +1550,12 @@ g_raid_md_write_nvidia(struct g_raid_md_ sd->sd_rebuild_pos / vol->v_sectorsize; } else pd->pd_meta->disk_status = NVIDIA_S_CURRENT; - if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1) { - pd->pd_meta->disk_number = sd->sd_pos; - pd->pd_meta->raid0_ident = 0xff; - pd->pd_meta->raid1_ident = 0; - } else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E) { - pd->pd_meta->disk_number = sd->sd_pos / meta->raid1_disks; - pd->pd_meta->raid0_ident = sd->sd_pos % meta->raid1_disks; - pd->pd_meta->raid1_ident = sd->sd_pos / meta->raid1_disks; - } else { - pd->pd_meta->disk_number = sd->sd_pos; - pd->pd_meta->raid0_ident = 0; - pd->pd_meta->raid1_ident = 0xff; - } - } +*/ } G_RAID_DEBUG(1, "Writing NVidia metadata to %s", g_raid_get_diskname(disk)); g_raid_md_nvidia_print(pd->pd_meta); nvidia_meta_write(disk->d_consumer, pd->pd_meta); } -#endif return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103222000.p2MK0Rpq069638>