summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/geom/class/concat/geom_concat.c9
-rw-r--r--sbin/geom/class/label/geom_label.c8
-rw-r--r--sbin/geom/class/mirror/geom_mirror.c4
-rw-r--r--sbin/geom/class/raid3/geom_raid3.c10
-rw-r--r--sbin/geom/class/shsec/geom_shsec.c10
-rw-r--r--sbin/geom/class/stripe/geom_stripe.c10
-rw-r--r--sys/geom/concat/g_concat.c11
-rw-r--r--sys/geom/concat/g_concat.h8
-rw-r--r--sys/geom/label/g_label.c16
-rw-r--r--sys/geom/label/g_label.h12
-rw-r--r--sys/geom/mirror/g_mirror.c4
-rw-r--r--sys/geom/mirror/g_mirror.h47
-rw-r--r--sys/geom/raid3/g_raid3.c20
-rw-r--r--sys/geom/raid3/g_raid3.h48
-rw-r--r--sys/geom/shsec/g_shsec.c9
-rw-r--r--sys/geom/shsec/g_shsec.h6
-rw-r--r--sys/geom/stripe/g_stripe.c11
-rw-r--r--sys/geom/stripe/g_stripe.h8
18 files changed, 212 insertions, 39 deletions
diff --git a/sbin/geom/class/concat/geom_concat.c b/sbin/geom/class/concat/geom_concat.c
index 5bb64ec..8fa5d64 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 b0dfcd1..16aa918 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 de24072..b7668b7 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 7f944c3..09d1f79 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 ae6594c..8a3509b 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 2ba362c..0320b27 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 a1e1765..49087ca 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 5cf8757..d5c40de 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 a2f6dbd..c8908c0 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 a084831..2d17bbc 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 45b480a..71456b4 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 64a8f98..03827ea 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 3befd8c..3309d47 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 3c11d4e..0f4ac18 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 5bc1ba8..acfa8fb 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 08b8a29..af2e8a7 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 abf2608..e9dfeba 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 5d73141..b343e23 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 <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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
OpenPOWER on IntegriCloud