diff options
author | phk <phk@FreeBSD.org> | 2003-05-02 22:46:13 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-05-02 22:46:13 +0000 |
commit | 2a47b08091621c84d2d45229dcdb6753d5a56366 (patch) | |
tree | 167b9bb293bf61d98bdeb7e2f55bda158e7dc864 /sys/geom/geom_bsd_enc.c | |
parent | 6c2bb0c0915b99851b219ab760eecfc5067d2afc (diff) | |
download | FreeBSD-src-2a47b08091621c84d2d45229dcdb6753d5a56366.zip FreeBSD-src-2a47b08091621c84d2d45229dcdb6753d5a56366.tar.gz |
Make bsd_disklabel_le_enc calculate the checksum and fill it in.
(If there is a legitimate need to correctly encode and pack a
disklabel with an invalid checksum custom tools can be built for
that.)
Make bsd_disklabel_le_dec() validate the magics, number of partitions
(against a new parameter) and the checksum.
Vastly simplify the logic of the GEOM::BSD class implementation:
Let g_bsd_modify() always take a byte-stream label.
This simplifies all users, except the ioctl's which now have to
convert to a byte-stream first. Their loss.
g_bsd_modify() is called with topology held now, and it returns
with it held.
Always update the md5sum in g_bsd_modify(), otherwise the check
is no use after the first modification of the label. Make the
MD5 over the bytestream version of the label.
Move the rawoffset hack to g_bsd_modify() and remove all the
inram/ondisk conversions.
Don't configure hotspots in g_bsd_modify(), do it in taste instead,
we do not support moving the label to a different location on the
fly anyway.
This passes all current regression tests.
Diffstat (limited to 'sys/geom/geom_bsd_enc.c')
-rw-r--r-- | sys/geom/geom_bsd_enc.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/sys/geom/geom_bsd_enc.c b/sys/geom/geom_bsd_enc.c index 8292497..a3a7fd9 100644 --- a/sys/geom/geom_bsd_enc.c +++ b/sys/geom/geom_bsd_enc.c @@ -44,10 +44,12 @@ #include <sys/types.h> #include <sys/endian.h> #include <sys/disklabel.h> +#include <sys/errno.h> #ifdef _KERNEL #include <sys/systm.h> #else #include <string.h> +#include <stdio.h> #endif void @@ -61,12 +63,38 @@ bsd_partition_le_dec(u_char *ptr, struct partition *d) d->p_cpg = le16dec(ptr + 14); } -void -bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d) +int +bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart) { int i; + u_char *p, *pe; + uint16_t sum; d->d_magic = le32dec(ptr + 0); + if (d->d_magic != DISKMAGIC) + return(EINVAL); + + d->d_magic2 = le32dec(ptr + 132); + if (d->d_magic2 != DISKMAGIC) { +printf("HERE %s %d\n", __FILE__, __LINE__); + return(EINVAL); + } + + d->d_npartitions = le16dec(ptr + 138); + if (d->d_npartitions > maxpart) { +printf("HERE %s %d\n", __FILE__, __LINE__); + return(EINVAL); + } + + pe = ptr + 148 + 16 * d->d_npartitions; + sum = 0; + for (p = ptr; p < pe; p += 2) + sum ^= le16dec(p); + if (sum != 0) { +printf("HERE %s %d\n", __FILE__, __LINE__); + return(EINVAL); + } + d->d_type = le16dec(ptr + 4); d->d_subtype = le16dec(ptr + 6); bcopy(ptr + 8, d->d_typename, 16); @@ -97,13 +125,13 @@ bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d) d->d_spare[2] = le32dec(ptr + 120); d->d_spare[3] = le32dec(ptr + 124); d->d_spare[4] = le32dec(ptr + 128); - d->d_magic2 = le32dec(ptr + 132); d->d_checksum = le16dec(ptr + 136); d->d_npartitions = le16dec(ptr + 138); d->d_bbsize = le32dec(ptr + 140); d->d_sbsize = le32dec(ptr + 144); for (i = 0; i < MAXPARTITIONS; i++) bsd_partition_le_dec(ptr + 148 + 16 * i, &d->d_partitions[i]); + return(0); } void @@ -121,6 +149,8 @@ void bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d) { int i; + u_char *p, *pe; + uint16_t sum; le32enc(ptr + 0, d->d_magic); le16enc(ptr + 4, d->d_type); @@ -154,10 +184,15 @@ bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d) le32enc(ptr + 124, d->d_spare[3]); le32enc(ptr + 128, d->d_spare[4]); le32enc(ptr + 132, d->d_magic2); - le16enc(ptr + 136, d->d_checksum); + le16enc(ptr + 136, 0); le16enc(ptr + 138, d->d_npartitions); le32enc(ptr + 140, d->d_bbsize); le32enc(ptr + 144, d->d_sbsize); - for (i = 0; i < MAXPARTITIONS; i++) + for (i = 0; i < d->d_npartitions; i++) bsd_partition_le_enc(ptr + 148 + 16 * i, &d->d_partitions[i]); + pe = ptr + 148 + 16 * d->d_npartitions; + sum = 0; + for (p = ptr; p < pe; p += 2) + sum ^= le16dec(p); + le16enc(ptr + 136, sum); } |