diff options
author | pjd <pjd@FreeBSD.org> | 2005-01-20 22:14:05 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2005-01-20 22:14:05 +0000 |
commit | 9e051a0e238885a44007a5c463a88a6e8789c597 (patch) | |
tree | 1109457439bd33fb41bdb7c50ac7e7f60a89576a /sys | |
parent | 45ddfd5fbbdc694275a8e3cfca3f550f3e7fa52b (diff) | |
download | FreeBSD-src-9e051a0e238885a44007a5c463a88a6e8789c597.zip FreeBSD-src-9e051a0e238885a44007a5c463a88a6e8789c597.tar.gz |
Protect against recursive slices creation in simlar way as it is done
in BSD class, ie. if provider below us uses the same metadata, don't
create slices based on the metadata.
This allows to create slices on geoms with rank != 1 without hacks.
Discussed with: phk
Approved by: phk
MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/geom/geom_mbr.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/sys/geom/geom_mbr.c b/sys/geom/geom_mbr.c index bedfa0c..868c0e0 100644 --- a/sys/geom/geom_mbr.c +++ b/sys/geom/geom_mbr.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bio.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/md5.h> #include <sys/diskmbr.h> #include <sys/sbuf.h> @@ -82,6 +83,7 @@ struct g_mbr_softc { int type [NDOSPART]; u_int sectorsize; u_char sec0[512]; + u_char slicesum[16]; }; static int @@ -90,6 +92,7 @@ g_mbr_modify(struct g_geom *gp, struct g_mbr_softc *ms, u_char *sec0) int i, error; off_t l[NDOSPART]; struct dos_partition ndp[NDOSPART], *dp; + MD5_CTX md5sum; g_topology_assert(); @@ -150,6 +153,15 @@ g_mbr_modify(struct g_geom *gp, struct g_mbr_softc *ms, u_char *sec0) ms->sectorsize, "%ss%d", gp->name, 1 + i); } bcopy(sec0, ms->sec0, 512); + + /* + * Calculate MD5 from the first sector and use it for avoiding + * recursive slices creation. + */ + MD5Init(&md5sum); + MD5Update(&md5sum, ms->sec0, sizeof(ms->sec0)); + MD5Final(ms->slicesum, &md5sum); + return (0); } @@ -215,6 +227,9 @@ g_mbr_start(struct bio *bp) if (g_handleattr_off_t(bp, "MBR::offset", gsp->slices[idx].offset)) return (1); + if (g_handleattr(bp, "MBR::slicesum", mp->slicesum, + sizeof(mp->slicesum))) + return (1); } return (0); @@ -247,6 +262,8 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist) struct g_mbr_softc *ms; u_int fwsectors, sectorsize; u_char *buf; + u_char hash[16]; + MD5_CTX md5sum; g_trace(G_T_TOPOLOGY, "mbr_taste(%s,%s)", mp->name, pp->name); g_topology_assert(); @@ -255,13 +272,6 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist) return (NULL); g_topology_unlock(); do { - /* XXX: phk think about this! */ - if (gp->rank != 2 && - strcmp(pp->geom->class->name, "LABEL") != 0 && - strcmp(pp->geom->class->name, "MIRROR") != 0 && - strcmp(pp->geom->class->name, "NOP") != 0) { - break; - } error = g_getattr("GEOM::fwsectors", cp, &fwsectors); if (error) fwsectors = 17; @@ -272,6 +282,22 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist) buf = g_read_data(cp, 0, sectorsize, &error); if (buf == NULL || error != 0) break; + + /* + * Calculate MD5 from the first sector and use it for avoiding + * recursive slices creation. + */ + bcopy(buf, ms->sec0, 512); + MD5Init(&md5sum); + MD5Update(&md5sum, ms->sec0, sizeof(ms->sec0)); + MD5Final(ms->slicesum, &md5sum); + + error = g_getattr("MBR::slicesum", cp, &hash); + if (!error && !bcmp(ms->slicesum, hash, sizeof(hash))) { + g_free(buf); + break; + } + g_topology_lock(); g_mbr_modify(gp, ms, buf); g_topology_unlock(); |