diff --git a/sbin/geom/class/concat/geom_concat.c b/sbin/geom/class/concat/geom_concat.c index 5bb64ec52dab..8fa5d64d9f88 100644 --- a/sbin/geom/class/concat/geom_concat.c +++ b/sbin/geom/class/concat/geom_concat.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -180,6 +180,13 @@ concat_label(struct gctl_req *req) name += strlen(_PATH_DEV); strlcpy(md.md_provider, name, sizeof(md.md_provider)); } + md.md_provsize = g_get_mediasize(name); + if (md.md_provsize == 0) { + fprintf(stderr, "Can't get mediasize of %s: %s.\n", + name, strerror(errno)); + gctl_error(req, "Not fully done."); + continue; + } concat_metadata_encode(&md, sector); error = g_metadata_store(name, sector, sizeof(sector)); if (error != 0) { diff --git a/sbin/geom/class/label/geom_label.c b/sbin/geom/class/label/geom_label.c index b0dfcd1920b4..16aa918b7c37 100644 --- a/sbin/geom/class/label/geom_label.c +++ b/sbin/geom/class/label/geom_label.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -149,6 +149,12 @@ label_label(struct gctl_req *req) return; } strlcpy(md.md_label, label, sizeof(md.md_label)); + md.md_provsize = g_get_mediasize(name); + if (md.md_provsize == 0) { + gctl_error(req, "Can't get mediasize of %s: %s.", name, + strerror(errno)); + return; + } /* * Ok, store metadata. diff --git a/sbin/geom/class/mirror/geom_mirror.c b/sbin/geom/class/mirror/geom_mirror.c index de24072621cb..b7668b7c4bc3 100644 --- a/sbin/geom/class/mirror/geom_mirror.c +++ b/sbin/geom/class/mirror/geom_mirror.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -268,6 +268,8 @@ mirror_label(struct gctl_req *req) md.md_did = arc4random(); md.md_priority = i - 1; + md.md_provsize = g_get_mediasize(str); + assert(md.md_provsize != 0); if (!*hardcode) bzero(md.md_provider, sizeof(md.md_provider)); else { diff --git a/sbin/geom/class/raid3/geom_raid3.c b/sbin/geom/class/raid3/geom_raid3.c index 7f944c316798..09d1f7939d65 100644 --- a/sbin/geom/class/raid3/geom_raid3.c +++ b/sbin/geom/class/raid3/geom_raid3.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -265,14 +265,16 @@ raid3_label(struct gctl_req *req) snprintf(param, sizeof(param), "arg%u", i); str = gctl_get_asciiparam(req, param); - msize = g_get_mediasize(str) - g_get_sectorsize(str); - if (mediasize < msize) { + msize = g_get_mediasize(str); + ssize = g_get_sectorsize(str); + if (mediasize < msize - ssize) { fprintf(stderr, "warning: %s: only %jd bytes from %jd bytes used.\n", - str, (intmax_t)mediasize, (intmax_t)msize); + str, (intmax_t)mediasize, (intmax_t)(msize - ssize)); } md.md_no = i - 1; + md.md_provsize = msize; if (!*hardcode) bzero(md.md_provider, sizeof(md.md_provider)); else { diff --git a/sbin/geom/class/shsec/geom_shsec.c b/sbin/geom/class/shsec/geom_shsec.c index ae6594ce0c09..8a3509bf31f3 100644 --- a/sbin/geom/class/shsec/geom_shsec.c +++ b/sbin/geom/class/shsec/geom_shsec.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -181,14 +181,16 @@ shsec_label(struct gctl_req *req) snprintf(param, sizeof(param), "arg%u", i); name = gctl_get_asciiparam(req, param); - msize = g_get_mediasize(name) - g_get_sectorsize(name); - if (compsize < msize) { + msize = g_get_mediasize(name); + ssize = g_get_sectorsize(name); + if (compsize < msize - ssize) { fprintf(stderr, "warning: %s: only %jd bytes from %jd bytes used.\n", - name, (intmax_t)compsize, (intmax_t)msize); + name, (intmax_t)compsize, (intmax_t)(msize - ssize)); } md.md_no = i - 1; + md.md_provsize = msize; if (!*hardcode) bzero(md.md_provider, sizeof(md.md_provider)); else { diff --git a/sbin/geom/class/stripe/geom_stripe.c b/sbin/geom/class/stripe/geom_stripe.c index 2ba362c3fe25..0320b27ef9ac 100644 --- a/sbin/geom/class/stripe/geom_stripe.c +++ b/sbin/geom/class/stripe/geom_stripe.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -210,14 +210,16 @@ stripe_label(struct gctl_req *req) snprintf(param, sizeof(param), "arg%u", i); name = gctl_get_asciiparam(req, param); - msize = g_get_mediasize(name) - g_get_sectorsize(name); - if (compsize < msize) { + msize = g_get_mediasize(name); + ssize = g_get_sectorsize(name); + if (compsize < msize - ssize) { fprintf(stderr, "warning: %s: only %jd bytes from %jd bytes used.\n", - name, (intmax_t)compsize, (intmax_t)msize); + name, (intmax_t)compsize, (intmax_t)(msize - ssize)); } md.md_no = i - 1; + md.md_provsize = msize; if (!*hardcode) bzero(md.md_provider, sizeof(md.md_provider)); else { diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c index a1e1765485e9..49087ca2ce9e 100644 --- a/sys/geom/concat/g_concat.c +++ b/sys/geom/concat/g_concat.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -570,13 +570,18 @@ g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) } /* * Backward compatibility: - * There was no md_provider field in earlier versions of metadata. */ + /* There was no md_provider field in earlier versions of metadata. */ if (md.md_version < 3) bzero(md.md_provider, sizeof(md.md_provider)); + /* There was no md_provsize field in earlier versions of metadata. */ + if (md.md_version < 4) + md.md_provsize = pp->mediasize; if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) return (NULL); + if (md.md_provsize != pp->mediasize) + return (NULL); /* * Let's check if device already exists. @@ -661,6 +666,8 @@ g_concat_ctl_create(struct gctl_req *req, struct g_class *mp) md.md_no = 0; md.md_all = *nargs - 1; bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; /* Check all providers are valid */ for (no = 1; no < *nargs; no++) { diff --git a/sys/geom/concat/g_concat.h b/sys/geom/concat/g_concat.h index 5cf8757bb169..d5c40de868e7 100644 --- a/sys/geom/concat/g_concat.h +++ b/sys/geom/concat/g_concat.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,8 +39,9 @@ * 1 - Initial version number. * 2 - Added 'stop' command to gconcat(8). * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. */ -#define G_CONCAT_VERSION 3 +#define G_CONCAT_VERSION 4 #ifdef _KERNEL #define G_CONCAT_TYPE_MANUAL 0 @@ -93,6 +94,7 @@ struct g_concat_metadata { uint16_t md_no; /* Disk number. */ uint16_t md_all; /* Number of all disks. */ char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ }; static __inline void concat_metadata_encode(const struct g_concat_metadata *md, u_char *data) @@ -105,6 +107,7 @@ concat_metadata_encode(const struct g_concat_metadata *md, u_char *data) le16enc(data + 40, md->md_no); le16enc(data + 42, md->md_all); bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); } static __inline void concat_metadata_decode(const u_char *data, struct g_concat_metadata *md) @@ -117,5 +120,6 @@ concat_metadata_decode(const u_char *data, struct g_concat_metadata *md) md->md_no = le16dec(data + 40); md->md_all = le16dec(data + 42); bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); } #endif /* _G_CONCAT_H_ */ diff --git a/sys/geom/label/g_label.c b/sys/geom/label/g_label.c index a2f6dbdbb172..c8908c02c65e 100644 --- a/sys/geom/label/g_label.c +++ b/sys/geom/label/g_label.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -238,6 +238,20 @@ g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) pp->name); break; } + + /* + * Backward compatibility: + */ + /* + * There was no md_provsize field in earlier versions of + * metadata. + */ + if (md.md_version < 2) + md.md_provsize = pp->mediasize; + + if (md.md_provsize != pp->mediasize) + break; + g_label_create(NULL, mp, pp, md.md_label, G_LABEL_DIR, pp->mediasize - pp->sectorsize); } while (0); diff --git a/sys/geom/label/g_label.h b/sys/geom/label/g_label.h index a0848318c958..2d17bbcdaa01 100644 --- a/sys/geom/label/g_label.h +++ b/sys/geom/label/g_label.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,12 @@ #define G_LABEL_CLASS_NAME "LABEL" #define G_LABEL_MAGIC "GEOM::LABEL" -#define G_LABEL_VERSION 1 +/* + * Version history: + * 1 - Initial version number. + * 2 - Added md_provsize field to metadata. + */ +#define G_LABEL_VERSION 2 #define G_LABEL_DIR "label" #ifdef _KERNEL @@ -68,6 +73,7 @@ struct g_label_metadata { char md_magic[16]; /* Magic value. */ uint32_t md_version; /* Version number. */ char md_label[16]; /* Label. */ + uint64_t md_provsize; /* Provider's size. */ }; static __inline void label_metadata_encode(const struct g_label_metadata *md, u_char *data) @@ -76,6 +82,7 @@ label_metadata_encode(const struct g_label_metadata *md, u_char *data) bcopy(md->md_magic, data, sizeof(md->md_magic)); le32enc(data + 16, md->md_version); bcopy(md->md_label, data + 20, sizeof(md->md_label)); + le64enc(data + 36, md->md_provsize); } static __inline void label_metadata_decode(const u_char *data, struct g_label_metadata *md) @@ -84,5 +91,6 @@ label_metadata_decode(const u_char *data, struct g_label_metadata *md) bcopy(data, md->md_magic, sizeof(md->md_magic)); md->md_version = le32dec(data + 16); bcopy(data + 20, md->md_label, sizeof(md->md_label)); + md->md_provsize = le64dec(data + 36); } #endif /* _G_LABEL_H_ */ diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 45b480a4a864..71456b4aca86 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -669,6 +669,7 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk, md->md_syncid = 0; md->md_dflags = 0; md->md_sync_offset = 0; + md->md_provsize = 0; } else { md->md_did = disk->d_id; md->md_priority = disk->d_priority; @@ -683,6 +684,7 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk, disk->d_consumer->provider->name, sizeof(md->md_provider)); } + md->md_provsize = disk->d_consumer->provider->mediasize; } } @@ -2646,6 +2648,8 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) return (NULL); + if (md.md_provsize != 0 && md.md_provsize != pp->mediasize) + return (NULL); if ((md.md_dflags & G_MIRROR_DISK_FLAG_INACTIVE) != 0) { G_MIRROR_DEBUG(0, "Device %s: provider %s marked as inactive, skipping.", diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h index 64a8f981c252..03827eadb732 100644 --- a/sys/geom/mirror/g_mirror.h +++ b/sys/geom/mirror/g_mirror.h @@ -40,8 +40,9 @@ * 0 - Initial version number. * 1 - Added 'prefer' balance algorithm. * 2 - Added md_genid field to metadata. + * 3 - Added md_provsize field to metadata. */ -#define G_MIRROR_VERSION 2 +#define G_MIRROR_VERSION 3 #define G_MIRROR_BALANCE_NONE 0 #define G_MIRROR_BALANCE_ROUND_ROBIN 1 @@ -226,6 +227,7 @@ struct g_mirror_metadata { uint64_t md_mflags; /* Additional mirror flags. */ uint64_t md_dflags; /* Additional disk flags. */ char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ u_char md_hash[16]; /* MD5 hash. */ }; static __inline void @@ -250,10 +252,11 @@ mirror_metadata_encode(struct g_mirror_metadata *md, u_char *data) le64enc(data + 79, md->md_mflags); le64enc(data + 87, md->md_dflags); bcopy(md->md_provider, data + 95, 16); + le64enc(data + 111, md->md_provsize); MD5Init(&ctx); - MD5Update(&ctx, data, 111); + MD5Update(&ctx, data, 119); MD5Final(md->md_hash, &ctx); - bcopy(md->md_hash, data + 111, 16); + bcopy(md->md_hash, data + 119, 16); } static __inline int mirror_metadata_decode_v0v1(const u_char *data, struct g_mirror_metadata *md) @@ -283,6 +286,7 @@ mirror_metadata_decode_v0v1(const u_char *data, struct g_mirror_metadata *md) /* New fields. */ md->md_genid = 0; + md->md_provsize = 0; return (0); } @@ -312,6 +316,39 @@ mirror_metadata_decode_v2(const u_char *data, struct g_mirror_metadata *md) MD5Final(md->md_hash, &ctx); if (bcmp(md->md_hash, data + 111, 16) != 0) return (EINVAL); + + /* New fields. */ + md->md_provsize = 0; + + return (0); +} +static __inline int +mirror_metadata_decode_v3(const u_char *data, struct g_mirror_metadata *md) +{ + MD5_CTX ctx; + + bcopy(data + 20, md->md_name, 16); + md->md_mid = le32dec(data + 36); + md->md_did = le32dec(data + 40); + md->md_all = *(data + 44); + md->md_genid = le32dec(data + 45); + md->md_syncid = le32dec(data + 49); + md->md_priority = *(data + 53); + md->md_slice = le32dec(data + 54); + md->md_balance = *(data + 58); + md->md_mediasize = le64dec(data + 59); + md->md_sectorsize = le32dec(data + 67); + md->md_sync_offset = le64dec(data + 71); + md->md_mflags = le64dec(data + 79); + md->md_dflags = le64dec(data + 87); + bcopy(data + 95, md->md_provider, 16); + md->md_provsize = le64dec(data + 111); + bcopy(data + 119, md->md_hash, 16); + MD5Init(&ctx); + MD5Update(&ctx, data, 119); + MD5Final(md->md_hash, &ctx); + if (bcmp(md->md_hash, data + 119, 16) != 0) + return (EINVAL); return (0); } static __inline int @@ -329,6 +366,9 @@ mirror_metadata_decode(const u_char *data, struct g_mirror_metadata *md) case 2: error = mirror_metadata_decode_v2(data, md); break; + case 3: + error = mirror_metadata_decode_v3(data, md); + break; default: error = EINVAL; break; @@ -417,6 +457,7 @@ mirror_metadata_dump(const struct g_mirror_metadata *md) } printf("\n"); printf("hcprovider: %s\n", md->md_provider); + printf(" provsize: %ju\n", (uintmax_t)md->md_provsize); bzero(hash, sizeof(hash)); for (i = 0; i < 16; i++) { hash[i * 2] = hex[md->md_hash[i] >> 4]; diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index 3befd8cc7ec5..3309d473abbd 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -673,6 +673,7 @@ void g_raid3_fill_metadata(struct g_raid3_disk *disk, struct g_raid3_metadata *md) { struct g_raid3_softc *sc; + struct g_provider *pp; sc = disk->d_softc; strlcpy(md->md_magic, G_RAID3_MAGIC, sizeof(md->md_magic)); @@ -691,13 +692,18 @@ g_raid3_fill_metadata(struct g_raid3_disk *disk, struct g_raid3_metadata *md) md->md_sync_offset = disk->d_sync.ds_offset_done; else md->md_sync_offset = 0; - if ((disk->d_flags & G_RAID3_DISK_FLAG_HARDCODED) != 0 && - disk->d_consumer != NULL && disk->d_consumer->provider != NULL) { - strlcpy(md->md_provider, disk->d_consumer->provider->name, - sizeof(md->md_provider)); - } else { + if (disk->d_consumer != NULL && disk->d_consumer->provider != NULL) + pp = disk->d_consumer->provider; + else + pp = NULL; + if ((disk->d_flags & G_RAID3_DISK_FLAG_HARDCODED) != 0 && pp != NULL) + strlcpy(md->md_provider, pp->name, sizeof(md->md_provider)); + else bzero(md->md_provider, sizeof(md->md_provider)); - } + if (pp != NULL) + md->md_provsize = pp->mediasize; + else + md->md_provsize = 0; } void @@ -2886,6 +2892,8 @@ g_raid3_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) return (NULL); + if (md.md_provsize != 0 && md.md_provsize != pp->mediasize) + return (NULL); if (g_raid3_debug >= 2) raid3_metadata_dump(&md); diff --git a/sys/geom/raid3/g_raid3.h b/sys/geom/raid3/g_raid3.h index 3c11d4e71cfe..0f4ac188a2eb 100644 --- a/sys/geom/raid3/g_raid3.h +++ b/sys/geom/raid3/g_raid3.h @@ -41,8 +41,9 @@ * 1 - Added 'round-robin reading' algorithm. * 2 - Added 'verify reading' algorithm. * 3 - Added md_genid field to metadata. + * 4 - Added md_provsize field to metadata. */ -#define G_RAID3_VERSION 3 +#define G_RAID3_VERSION 4 #define G_RAID3_DISK_FLAG_DIRTY 0x0000000000000001ULL #define G_RAID3_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL @@ -235,6 +236,7 @@ struct g_raid3_metadata { uint64_t md_mflags; /* Additional device flags. */ uint64_t md_dflags; /* Additional disk flags. */ char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ u_char md_hash[16]; /* MD5 hash. */ }; static __inline void @@ -256,10 +258,11 @@ raid3_metadata_encode(struct g_raid3_metadata *md, u_char *data) le64enc(data + 72, md->md_mflags); le64enc(data + 80, md->md_dflags); bcopy(md->md_provider, data + 88, 16); + le64enc(data + 104, md->md_provsize); MD5Init(&ctx); - MD5Update(&ctx, data, 104); + MD5Update(&ctx, data, 112); MD5Final(md->md_hash, &ctx); - bcopy(md->md_hash, data + 104, 16); + bcopy(md->md_hash, data + 112, 16); } static __inline int raid3_metadata_decode_v0v1v2(const u_char *data, struct g_raid3_metadata *md) @@ -283,6 +286,11 @@ raid3_metadata_decode_v0v1v2(const u_char *data, struct g_raid3_metadata *md) MD5Final(md->md_hash, &ctx); if (bcmp(md->md_hash, data + 100, 16) != 0) return (EINVAL); + + /* New fields. */ + md->md_genid = 0; + md->md_provsize = 0; + return (0); } static __inline int @@ -308,6 +316,36 @@ raid3_metadata_decode_v3(const u_char *data, struct g_raid3_metadata *md) MD5Final(md->md_hash, &ctx); if (bcmp(md->md_hash, data + 104, 16) != 0) return (EINVAL); + + /* New fields. */ + md->md_provsize = 0; + + return (0); +} +static __inline int +raid3_metadata_decode_v4(const u_char *data, struct g_raid3_metadata *md) +{ + MD5_CTX ctx; + + bcopy(data + 20, md->md_name, 16); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + md->md_genid = le32dec(data + 44); + md->md_syncid = le32dec(data + 48); + md->md_mediasize = le64dec(data + 52); + md->md_sectorsize = le32dec(data + 60); + md->md_sync_offset = le64dec(data + 64); + md->md_mflags = le64dec(data + 72); + md->md_dflags = le64dec(data + 80); + bcopy(data + 88, md->md_provider, 16); + md->md_provsize = le64dec(data + 104); + bcopy(data + 112, md->md_hash, 16); + MD5Init(&ctx); + MD5Update(&ctx, data, 112); + MD5Final(md->md_hash, &ctx); + if (bcmp(md->md_hash, data + 112, 16) != 0) + return (EINVAL); return (0); } static __inline int @@ -326,6 +364,9 @@ raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md) case 3: error = raid3_metadata_decode_v3(data, md); break; + case 4: + error = raid3_metadata_decode_v4(data, md); + break; default: error = EINVAL; break; @@ -376,6 +417,7 @@ raid3_metadata_dump(const struct g_raid3_metadata *md) } printf("\n"); printf("hcprovider: %s\n", md->md_provider); + printf(" provsize: %ju\n", (uintmax_t)md->md_provsize); bzero(hash, sizeof(hash)); for (i = 0; i < 16; i++) { hash[i * 2] = hex[md->md_hash[i] >> 4]; diff --git a/sys/geom/shsec/g_shsec.c b/sys/geom/shsec/g_shsec.c index 5bc1ba8baaaa..acfa8fb7231d 100644 --- a/sys/geom/shsec/g_shsec.c +++ b/sys/geom/shsec/g_shsec.c @@ -660,8 +660,17 @@ g_shsec_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) pp->name); return (NULL); } + /* + * Backward compatibility: + */ + /* There was no md_provsize field in earlier versions of metadata. */ + if (md.md_version < 1) + md.md_provsize = pp->mediasize; + if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) return (NULL); + if (md.md_provsize != pp->mediasize) + return (NULL); /* * Let's check if device already exists. diff --git a/sys/geom/shsec/g_shsec.h b/sys/geom/shsec/g_shsec.h index 08b8a29bb3e5..af2e8a701d59 100644 --- a/sys/geom/shsec/g_shsec.h +++ b/sys/geom/shsec/g_shsec.h @@ -37,8 +37,9 @@ /* * Version history: * 0 - Initial version number. + * 1 - Added md_provsize field to metadata. */ -#define G_SHSEC_VERSION 0 +#define G_SHSEC_VERSION 1 #ifdef _KERNEL #define G_SHSEC_BFLAG_FIRST 0x1 @@ -85,6 +86,7 @@ struct g_shsec_metadata { uint16_t md_no; /* Disk number. */ uint16_t md_all; /* Number of all disks. */ char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ }; static __inline void shsec_metadata_encode(const struct g_shsec_metadata *md, u_char *data) @@ -97,6 +99,7 @@ shsec_metadata_encode(const struct g_shsec_metadata *md, u_char *data) le16enc(data + 40, md->md_no); le16enc(data + 42, md->md_all); bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); } static __inline void shsec_metadata_decode(const u_char *data, struct g_shsec_metadata *md) @@ -109,5 +112,6 @@ shsec_metadata_decode(const u_char *data, struct g_shsec_metadata *md) md->md_no = le16dec(data + 40); md->md_all = le16dec(data + 42); bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); } #endif /* _G_SHSEC_H_ */ diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c index abf2608419d0..e9dfeba4b072 100644 --- a/sys/geom/stripe/g_stripe.c +++ b/sys/geom/stripe/g_stripe.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -901,13 +901,18 @@ g_stripe_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) } /* * Backward compatibility: - * There was no md_provider field in earlier versions of metadata. */ + /* There was no md_provider field in earlier versions of metadata. */ if (md.md_version < 2) bzero(md.md_provider, sizeof(md.md_provider)); + /* There was no md_provsize field in earlier versions of metadata. */ + if (md.md_version < 3) + md.md_provsize = pp->mediasize; if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0) return (NULL); + if (md.md_provsize != pp->mediasize) + return (NULL); /* * Let's check if device already exists. @@ -999,6 +1004,8 @@ g_stripe_ctl_create(struct gctl_req *req, struct g_class *mp) } md.md_stripesize = *stripesize; bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; /* Check all providers are valid */ for (no = 1; no < *nargs; no++) { diff --git a/sys/geom/stripe/g_stripe.h b/sys/geom/stripe/g_stripe.h index 5d7314178c47..b343e235e589 100644 --- a/sys/geom/stripe/g_stripe.h +++ b/sys/geom/stripe/g_stripe.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Pawel Jakub Dawidek + * Copyright (c) 2004-2005 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,8 +39,9 @@ * 0 - Initial version number. * 1 - Added 'stop' command for gstripe(8). * 2 - Added md_provider field to metadata and '-h' option for gstripe(8). + * 3 - Added md_provsize field to metadata. */ -#define G_STRIPE_VERSION 2 +#define G_STRIPE_VERSION 3 #ifdef _KERNEL #define G_STRIPE_TYPE_MANUAL 0 @@ -88,6 +89,7 @@ struct g_stripe_metadata { uint16_t md_all; /* Number of all disks. */ uint32_t md_stripesize; /* Stripe size. */ char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ }; static __inline void stripe_metadata_encode(const struct g_stripe_metadata *md, u_char *data) @@ -101,6 +103,7 @@ stripe_metadata_encode(const struct g_stripe_metadata *md, u_char *data) le16enc(data + 42, md->md_all); le32enc(data + 44, md->md_stripesize); bcopy(md->md_provider, data + 48, sizeof(md->md_provider)); + le64enc(data + 64, md->md_provsize); } static __inline void stripe_metadata_decode(const u_char *data, struct g_stripe_metadata *md) @@ -114,6 +117,7 @@ stripe_metadata_decode(const u_char *data, struct g_stripe_metadata *md) md->md_all = le16dec(data + 42); md->md_stripesize = le32dec(data + 44); bcopy(data + 48, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 64); } #ifndef BITCOUNT