diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c index 85d8a21b3e83..10ee5713554e 100644 --- a/sys/geom/concat/g_concat.c +++ b/sys/geom/concat/g_concat.c @@ -678,7 +678,8 @@ g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) if (md.md_version < 4) md.md_provsize = pp->mediasize; - if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) + if (md.md_provider[0] != '\0' && + !g_compare_names(md.md_provider, pp->name)) return (NULL); if (md.md_provsize != pp->mediasize) return (NULL); diff --git a/sys/geom/geom.h b/sys/geom/geom.h index a42721eded0c..1dc6eb11ef87 100644 --- a/sys/geom/geom.h +++ b/sys/geom/geom.h @@ -238,6 +238,7 @@ void g_waitidlelock(void); /* geom_subr.c */ int g_access(struct g_consumer *cp, int nread, int nwrite, int nexcl); int g_attach(struct g_consumer *cp, struct g_provider *pp); +int g_compare_names(const char *namea, const char *nameb); void g_destroy_consumer(struct g_consumer *cp); void g_destroy_geom(struct g_geom *pp); void g_destroy_provider(struct g_provider *pp); diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index b001c5fcaed0..a0958f30da0b 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -1017,6 +1017,43 @@ g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len) return (0); } +static int +g_get_device_prefix_len(const char *name) +{ + int len; + + if (strncmp(name, "ada", 3) == 0) + len = 3; + else if (strncmp(name, "ad", 2) == 0) + len = 2; + else + return (0); + if (name[len] < '0' || name[len] > '9') + return (0); + do { + len++; + } while (name[len] >= '0' && name[len] <= '9'); + return (len); +} + +int +g_compare_names(const char *namea, const char *nameb) +{ + int deva, devb; + + if (strcmp(namea, nameb) == 0) + return (1); + deva = g_get_device_prefix_len(namea); + if (deva == 0) + return (0); + devb = g_get_device_prefix_len(nameb); + if (devb == 0) + return (0); + if (strcmp(namea + deva, nameb + devb) == 0) + return (1); + return (0); +} + #if defined(DIAGNOSTIC) || defined(DDB) /* * This function walks the mesh and returns a non-zero integer if it diff --git a/sys/geom/journal/g_journal.c b/sys/geom/journal/g_journal.c index 48c03a1cd5c2..906a1e46a2ca 100644 --- a/sys/geom/journal/g_journal.c +++ b/sys/geom/journal/g_journal.c @@ -2527,7 +2527,8 @@ g_journal_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) return (NULL); gp = NULL; - if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) + if (md.md_provider[0] != '\0' && + !g_compare_names(md.md_provider, pp->name)) return (NULL); if (md.md_provsize != 0 && md.md_provsize != pp->mediasize) return (NULL); diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 326851f96c9d..a2780d7c9634 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -3007,7 +3007,8 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) return (NULL); gp = NULL; - if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) + if (md.md_provider[0] != '\0' && + !g_compare_names(md.md_provider, pp->name)) return (NULL); if (md.md_provsize != 0 && md.md_provsize != pp->mediasize) return (NULL); diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index 6cc20947ef54..67e44196c364 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -3329,7 +3329,8 @@ g_raid3_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) return (NULL); gp = NULL; - if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) + if (md.md_provider[0] != '\0' && + !g_compare_names(md.md_provider, pp->name)) return (NULL); if (md.md_provsize != 0 && md.md_provsize != pp->mediasize) return (NULL); diff --git a/sys/geom/shsec/g_shsec.c b/sys/geom/shsec/g_shsec.c index ee2cf4bab554..a2d9e1273243 100644 --- a/sys/geom/shsec/g_shsec.c +++ b/sys/geom/shsec/g_shsec.c @@ -673,7 +673,8 @@ g_shsec_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) if (md.md_version < 1) md.md_provsize = pp->mediasize; - if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) + if (md.md_provider[0] != '\0' && + !g_compare_names(md.md_provider, pp->name)) return (NULL); if (md.md_provsize != pp->mediasize) return (NULL); diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c index add0be0f3132..b8faffdb02f8 100644 --- a/sys/geom/stripe/g_stripe.c +++ b/sys/geom/stripe/g_stripe.c @@ -952,7 +952,8 @@ g_stripe_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) if (md.md_version < 3) md.md_provsize = pp->mediasize; - if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) + if (md.md_provider[0] != '\0' && + !g_compare_names(md.md_provider, pp->name)) return (NULL); if (md.md_provsize != pp->mediasize) return (NULL); diff --git a/sys/geom/virstor/g_virstor.c b/sys/geom/virstor/g_virstor.c index d48a2b1ef9a1..509aca1faf2d 100644 --- a/sys/geom/virstor/g_virstor.c +++ b/sys/geom/virstor/g_virstor.c @@ -809,10 +809,9 @@ g_virstor_taste(struct g_class *mp, struct g_provider *pp, int flags) /* If the provider name is hardcoded, use the offered provider only * if it's been offered with its proper name (the one used in * the label command). */ - if (md.provider[0] != '\0') { - if (strcmp(md.provider, pp->name) != 0) - return (NULL); - } + if (md.provider[0] != '\0' && + !g_compare_names(md.provider, pp->name)) + return (NULL); /* Iterate all geoms this class already knows about to see if a new * geom instance of this class needs to be created (in case the provider