md_ddf.c (234899) | md_ddf.c (234940) |
---|---|
1/*- 2 * Copyright (c) 2012 Alexander Motin <mav@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2012 Alexander Motin <mav@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/geom/raid/md_ddf.c 234899 2012-05-01 18:00:31Z mav $"); | 28__FBSDID("$FreeBSD: head/sys/geom/raid/md_ddf.c 234940 2012-05-03 05:32:56Z mav $"); |
29 30#include <sys/param.h> 31#include <sys/bio.h> 32#include <sys/endian.h> 33#include <sys/kernel.h> 34#include <sys/kobj.h> 35#include <sys/limits.h> 36#include <sys/lock.h> --- 46 unchanged lines hidden (view full) --- 83struct g_raid_md_ddf_pervolume { 84 struct ddf_vol_meta pv_meta; 85 int pv_started; 86 struct callout pv_start_co; /* STARTING state timer. */ 87}; 88 89struct g_raid_md_ddf_object { 90 struct g_raid_md_object mdio_base; | 29 30#include <sys/param.h> 31#include <sys/bio.h> 32#include <sys/endian.h> 33#include <sys/kernel.h> 34#include <sys/kobj.h> 35#include <sys/limits.h> 36#include <sys/lock.h> --- 46 unchanged lines hidden (view full) --- 83struct g_raid_md_ddf_pervolume { 84 struct ddf_vol_meta pv_meta; 85 int pv_started; 86 struct callout pv_start_co; /* STARTING state timer. */ 87}; 88 89struct g_raid_md_ddf_object { 90 struct g_raid_md_object mdio_base; |
91 u_int mdio_bigendian; |
|
91 struct ddf_meta mdio_meta; 92 int mdio_starting; 93 struct callout mdio_start_co; /* STARTING state timer. */ 94 int mdio_started; 95 struct root_hold_token *mdio_rootmount; /* Root mount delay token. */ 96}; 97 | 92 struct ddf_meta mdio_meta; 93 int mdio_starting; 94 struct callout mdio_start_co; /* STARTING state timer. */ 95 int mdio_started; 96 struct root_hold_token *mdio_rootmount; /* Root mount delay token. */ 97}; 98 |
98static g_raid_md_create_t g_raid_md_create_ddf; | 99static g_raid_md_create_req_t g_raid_md_create_req_ddf; |
99static g_raid_md_taste_t g_raid_md_taste_ddf; 100static g_raid_md_event_t g_raid_md_event_ddf; 101static g_raid_md_volume_event_t g_raid_md_volume_event_ddf; 102static g_raid_md_ctl_t g_raid_md_ctl_ddf; 103static g_raid_md_write_t g_raid_md_write_ddf; 104static g_raid_md_fail_disk_t g_raid_md_fail_disk_ddf; 105static g_raid_md_free_disk_t g_raid_md_free_disk_ddf; 106static g_raid_md_free_volume_t g_raid_md_free_volume_ddf; 107static g_raid_md_free_t g_raid_md_free_ddf; 108 109static kobj_method_t g_raid_md_ddf_methods[] = { | 100static g_raid_md_taste_t g_raid_md_taste_ddf; 101static g_raid_md_event_t g_raid_md_event_ddf; 102static g_raid_md_volume_event_t g_raid_md_volume_event_ddf; 103static g_raid_md_ctl_t g_raid_md_ctl_ddf; 104static g_raid_md_write_t g_raid_md_write_ddf; 105static g_raid_md_fail_disk_t g_raid_md_fail_disk_ddf; 106static g_raid_md_free_disk_t g_raid_md_free_disk_ddf; 107static g_raid_md_free_volume_t g_raid_md_free_volume_ddf; 108static g_raid_md_free_t g_raid_md_free_ddf; 109 110static kobj_method_t g_raid_md_ddf_methods[] = { |
110 KOBJMETHOD(g_raid_md_create, g_raid_md_create_ddf), | 111 KOBJMETHOD(g_raid_md_create_req, g_raid_md_create_req_ddf), |
111 KOBJMETHOD(g_raid_md_taste, g_raid_md_taste_ddf), 112 KOBJMETHOD(g_raid_md_event, g_raid_md_event_ddf), 113 KOBJMETHOD(g_raid_md_volume_event, g_raid_md_volume_event_ddf), 114 KOBJMETHOD(g_raid_md_ctl, g_raid_md_ctl_ddf), 115 KOBJMETHOD(g_raid_md_write, g_raid_md_write_ddf), 116 KOBJMETHOD(g_raid_md_fail_disk, g_raid_md_fail_disk_ddf), 117 KOBJMETHOD(g_raid_md_free_disk, g_raid_md_free_disk_ddf), 118 KOBJMETHOD(g_raid_md_free_volume, g_raid_md_free_volume_ddf), --- 438 unchanged lines hidden (view full) --- 557} 558 559static void 560ddf_meta_create(struct g_raid_disk *disk, struct ddf_meta *sample) 561{ 562 struct timespec ts; 563 struct clocktime ct; 564 struct g_raid_md_ddf_perdisk *pd; | 112 KOBJMETHOD(g_raid_md_taste, g_raid_md_taste_ddf), 113 KOBJMETHOD(g_raid_md_event, g_raid_md_event_ddf), 114 KOBJMETHOD(g_raid_md_volume_event, g_raid_md_volume_event_ddf), 115 KOBJMETHOD(g_raid_md_ctl, g_raid_md_ctl_ddf), 116 KOBJMETHOD(g_raid_md_write, g_raid_md_write_ddf), 117 KOBJMETHOD(g_raid_md_fail_disk, g_raid_md_fail_disk_ddf), 118 KOBJMETHOD(g_raid_md_free_disk, g_raid_md_free_disk_ddf), 119 KOBJMETHOD(g_raid_md_free_volume, g_raid_md_free_volume_ddf), --- 438 unchanged lines hidden (view full) --- 558} 559 560static void 561ddf_meta_create(struct g_raid_disk *disk, struct ddf_meta *sample) 562{ 563 struct timespec ts; 564 struct clocktime ct; 565 struct g_raid_md_ddf_perdisk *pd; |
566 struct g_raid_md_ddf_object *mdi; |
|
565 struct ddf_meta *meta; 566 struct ddf_pd_entry *pde; 567 off_t anchorlba; 568 u_int ss, pos, size; 569 int len, error; 570 char serial_buffer[24]; 571 572 if (sample->hdr == NULL) 573 sample = NULL; 574 | 567 struct ddf_meta *meta; 568 struct ddf_pd_entry *pde; 569 off_t anchorlba; 570 u_int ss, pos, size; 571 int len, error; 572 char serial_buffer[24]; 573 574 if (sample->hdr == NULL) 575 sample = NULL; 576 |
577 mdi = (struct g_raid_md_ddf_object *)disk->d_softc->sc_md; |
|
575 pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data; 576 meta = &pd->pd_meta; 577 ss = disk->d_consumer->provider->sectorsize; 578 anchorlba = disk->d_consumer->provider->mediasize / ss - 1; 579 580 meta->sectorsize = ss; | 578 pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data; 579 meta = &pd->pd_meta; 580 ss = disk->d_consumer->provider->sectorsize; 581 anchorlba = disk->d_consumer->provider->mediasize / ss - 1; 582 583 meta->sectorsize = ss; |
581 meta->bigendian = sample ? sample->bigendian : 0; | 584 meta->bigendian = sample ? sample->bigendian : mdi->mdio_bigendian; |
582 getnanotime(&ts); 583 clock_ts_to_ct(&ts, &ct); 584 585 /* Header */ 586 meta->hdr = malloc(ss, M_MD_DDF, M_WAITOK); 587 memset(meta->hdr, 0xff, ss); 588 if (sample) { 589 memcpy(meta->hdr, sample->hdr, sizeof(struct ddf_header)); --- 1417 unchanged lines hidden (view full) --- 2007 G_RAID_DEBUG1(1, sc, "Volume %s now has %d of %d disks", 2008 vol->v_name, have, need); 2009 if (have == need) 2010 g_raid_md_ddf_start(vol); 2011 } 2012} 2013 2014static int | 585 getnanotime(&ts); 586 clock_ts_to_ct(&ts, &ct); 587 588 /* Header */ 589 meta->hdr = malloc(ss, M_MD_DDF, M_WAITOK); 590 memset(meta->hdr, 0xff, ss); 591 if (sample) { 592 memcpy(meta->hdr, sample->hdr, sizeof(struct ddf_header)); --- 1417 unchanged lines hidden (view full) --- 2010 G_RAID_DEBUG1(1, sc, "Volume %s now has %d of %d disks", 2011 vol->v_name, have, need); 2012 if (have == need) 2013 g_raid_md_ddf_start(vol); 2014 } 2015} 2016 2017static int |
2015g_raid_md_create_ddf(struct g_raid_md_object *md, struct g_class *mp, 2016 struct g_geom **gp) | 2018g_raid_md_create_req_ddf(struct g_raid_md_object *md, struct g_class *mp, 2019 struct gctl_req *req, struct g_geom **gp) |
2017{ 2018 struct g_geom *geom; 2019 struct g_raid_softc *sc; | 2020{ 2021 struct g_geom *geom; 2022 struct g_raid_softc *sc; |
2023 struct g_raid_md_ddf_object *mdi, *mdi1; 2024 char name[16]; 2025 const char *fmtopt; 2026 int be = 1; |
|
2020 | 2027 |
2028 mdi = (struct g_raid_md_ddf_object *)md; 2029 fmtopt = gctl_get_asciiparam(req, "fmtopt"); 2030 if (fmtopt == NULL || strcasecmp(fmtopt, "BE") == 0) 2031 be = 1; 2032 else if (strcasecmp(fmtopt, "LE") == 0) 2033 be = 0; 2034 else { 2035 gctl_error(req, "Incorrect fmtopt argument."); 2036 return (G_RAID_MD_TASTE_FAIL); 2037 } 2038 |
|
2021 /* Search for existing node. */ 2022 LIST_FOREACH(geom, &mp->geom, geom) { 2023 sc = geom->softc; 2024 if (sc == NULL) 2025 continue; 2026 if (sc->sc_stopping != 0) 2027 continue; 2028 if (sc->sc_md->mdo_class != md->mdo_class) 2029 continue; | 2039 /* Search for existing node. */ 2040 LIST_FOREACH(geom, &mp->geom, geom) { 2041 sc = geom->softc; 2042 if (sc == NULL) 2043 continue; 2044 if (sc->sc_stopping != 0) 2045 continue; 2046 if (sc->sc_md->mdo_class != md->mdo_class) 2047 continue; |
2048 mdi1 = (struct g_raid_md_ddf_object *)sc->sc_md; 2049 if (mdi1->mdio_bigendian != be) 2050 continue; |
|
2030 break; 2031 } 2032 if (geom != NULL) { 2033 *gp = geom; 2034 return (G_RAID_MD_TASTE_EXISTING); 2035 } 2036 2037 /* Create new one if not found. */ | 2051 break; 2052 } 2053 if (geom != NULL) { 2054 *gp = geom; 2055 return (G_RAID_MD_TASTE_EXISTING); 2056 } 2057 2058 /* Create new one if not found. */ |
2038 sc = g_raid_create_node(mp, "DDF", md); | 2059 mdi->mdio_bigendian = be; 2060 snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE"); 2061 sc = g_raid_create_node(mp, name, md); |
2039 if (sc == NULL) 2040 return (G_RAID_MD_TASTE_FAIL); 2041 md->mdo_softc = sc; 2042 *gp = sc->sc_geom; 2043 return (G_RAID_MD_TASTE_NEW); 2044} 2045 2046static int 2047g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp, 2048 struct g_consumer *cp, struct g_geom **gp) 2049{ 2050 struct g_consumer *rcp; 2051 struct g_provider *pp; 2052 struct g_raid_softc *sc; 2053 struct g_raid_disk *disk; 2054 struct ddf_meta meta; 2055 struct g_raid_md_ddf_perdisk *pd; | 2062 if (sc == NULL) 2063 return (G_RAID_MD_TASTE_FAIL); 2064 md->mdo_softc = sc; 2065 *gp = sc->sc_geom; 2066 return (G_RAID_MD_TASTE_NEW); 2067} 2068 2069static int 2070g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp, 2071 struct g_consumer *cp, struct g_geom **gp) 2072{ 2073 struct g_consumer *rcp; 2074 struct g_provider *pp; 2075 struct g_raid_softc *sc; 2076 struct g_raid_disk *disk; 2077 struct ddf_meta meta; 2078 struct g_raid_md_ddf_perdisk *pd; |
2079 struct g_raid_md_ddf_object *mdi; |
|
2056 struct g_geom *geom; | 2080 struct g_geom *geom; |
2057 int error, result, len; | 2081 int error, result, len, be; |
2058 char name[16]; 2059 2060 G_RAID_DEBUG(1, "Tasting DDF on %s", cp->provider->name); | 2082 char name[16]; 2083 2084 G_RAID_DEBUG(1, "Tasting DDF on %s", cp->provider->name); |
2085 mdi = (struct g_raid_md_ddf_object *)md; |
|
2061 pp = cp->provider; 2062 2063 /* Read metadata from device. */ 2064 if (g_access(cp, 1, 0, 0) != 0) 2065 return (G_RAID_MD_TASTE_FAIL); 2066 g_topology_unlock(); 2067 bzero(&meta, sizeof(meta)); 2068 error = ddf_meta_read(cp, &meta); 2069 g_topology_lock(); 2070 g_access(cp, -1, 0, 0); 2071 if (error != 0) 2072 return (G_RAID_MD_TASTE_FAIL); | 2086 pp = cp->provider; 2087 2088 /* Read metadata from device. */ 2089 if (g_access(cp, 1, 0, 0) != 0) 2090 return (G_RAID_MD_TASTE_FAIL); 2091 g_topology_unlock(); 2092 bzero(&meta, sizeof(meta)); 2093 error = ddf_meta_read(cp, &meta); 2094 g_topology_lock(); 2095 g_access(cp, -1, 0, 0); 2096 if (error != 0) 2097 return (G_RAID_MD_TASTE_FAIL); |
2098 be = meta.bigendian; |
|
2073 2074 /* Metadata valid. Print it. */ 2075 g_raid_md_ddf_print(&meta); 2076 2077 /* Search for matching node. */ 2078 sc = NULL; 2079 LIST_FOREACH(geom, &mp->geom, geom) { 2080 sc = geom->softc; 2081 if (sc == NULL) 2082 continue; 2083 if (sc->sc_stopping != 0) 2084 continue; 2085 if (sc->sc_md->mdo_class != md->mdo_class) 2086 continue; | 2099 2100 /* Metadata valid. Print it. */ 2101 g_raid_md_ddf_print(&meta); 2102 2103 /* Search for matching node. */ 2104 sc = NULL; 2105 LIST_FOREACH(geom, &mp->geom, geom) { 2106 sc = geom->softc; 2107 if (sc == NULL) 2108 continue; 2109 if (sc->sc_stopping != 0) 2110 continue; 2111 if (sc->sc_md->mdo_class != md->mdo_class) 2112 continue; |
2113 mdi = (struct g_raid_md_ddf_object *)sc->sc_md; 2114 if (mdi->mdio_bigendian != be) 2115 continue; |
|
2087 break; 2088 } 2089 2090 /* Found matching node. */ 2091 if (geom != NULL) { 2092 G_RAID_DEBUG(1, "Found matching array %s", sc->sc_name); 2093 result = G_RAID_MD_TASTE_EXISTING; 2094 2095 } else { /* Not found matching node -- create one. */ 2096 result = G_RAID_MD_TASTE_NEW; | 2116 break; 2117 } 2118 2119 /* Found matching node. */ 2120 if (geom != NULL) { 2121 G_RAID_DEBUG(1, "Found matching array %s", sc->sc_name); 2122 result = G_RAID_MD_TASTE_EXISTING; 2123 2124 } else { /* Not found matching node -- create one. */ 2125 result = G_RAID_MD_TASTE_NEW; |
2097 snprintf(name, sizeof(name), "DDF"); | 2126 mdi->mdio_bigendian = be; 2127 snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE"); |
2098 sc = g_raid_create_node(mp, name, md); 2099 md->mdo_softc = sc; 2100 geom = sc->sc_geom; 2101 } 2102 2103 rcp = g_new_consumer(geom); 2104 g_attach(rcp, pp); 2105 if (g_access(rcp, 1, 1, 1) != 0) --- 906 unchanged lines hidden --- | 2128 sc = g_raid_create_node(mp, name, md); 2129 md->mdo_softc = sc; 2130 geom = sc->sc_geom; 2131 } 2132 2133 rcp = g_new_consumer(geom); 2134 g_attach(rcp, pp); 2135 if (g_access(rcp, 1, 1, 1) != 0) --- 906 unchanged lines hidden --- |