Hi Christophe The following patches makes kpartx with dos partitions behave correctly on powerpc and makes it a little bit easier to read. You can also pull this changes from http://137.250.31.225/rsync/git/linux/storage/multipath-tools.git. Bastian Use endian.h and byteswap.h. --- commit 2be146862254c9941cb0754fadd45cb34dd05694 tree 1f6997be9d4b30258d6abfa25aefb2106b61ff96 parent f67cb7d39e9f0a0046d97af3bf78e8c4be2e68bf author Bastian Blank <waldi@xxxxxxxxxx> Thu, 29 Sep 2005 12:55:36 +0000 committer Bastian Blank <waldi@xxxxxxxxxx> Thu, 29 Sep 2005 12:55:36 +0000 kpartx/byteorder.h | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diff --git a/kpartx/byteorder.h b/kpartx/byteorder.h --- a/kpartx/byteorder.h +++ b/kpartx/byteorder.h @@ -1,15 +1,19 @@ #ifndef BYTEORDER_H_INCLUDED #define BYTEORDER_H_INCLUDED -#if defined (__s390__) || defined (__s390x__) -#define le32_to_cpu(x) ( \ - (*(((unsigned char *) &(x)))) + \ - (*(((unsigned char *) &(x))+1) << 8) + \ - (*(((unsigned char *) &(x))+2) << 16) + \ - (*(((unsigned char *) &(x))+3) << 24) \ - ) +#ifdef __linux__ +# include <endian.h> +# include <byteswap.h> #else -#define le32_to_cpu(x) (x) +# error unsupported +#endif + +#if BYTE_ORDER == LITTLE_ENDIAN +# define le32_to_cpu(x) (x) +#elif BYTE_ORDER == BIG_ENDIAN +# define le32_to_cpu(x) bswap_32(x) +#else +# error unsupported #endif #endif /* BYTEORDER_H_INCLUDED */ !-------------------------------------------------------------flip- Don't use unalligned pointers, always copy the structures to a properly alligned piece of memory. This triggered undefined behaviour. --- commit 6399c88650be9835b90bad91a7b6268db8db3303 tree aa0fb4438812f0a116d4e7a7db092bfd45edfcf3 parent 2be146862254c9941cb0754fadd45cb34dd05694 author Bastian Blank <waldi@xxxxxxxxxx> Thu, 29 Sep 2005 13:01:45 +0000 committer Bastian Blank <waldi@xxxxxxxxxx> Thu, 29 Sep 2005 13:01:45 +0000 kpartx/dos.c | 43 ++++++++++++++++++++----------------------- 1 files changed, 20 insertions(+), 23 deletions(-) diff --git a/kpartx/dos.c b/kpartx/dos.c --- a/kpartx/dos.c +++ b/kpartx/dos.c @@ -1,6 +1,7 @@ #include "kpartx.h" #include "byteorder.h" #include <stdio.h> +#include <string.h> #include "dos.h" static int @@ -12,7 +13,7 @@ static int read_extended_partition(int fd, struct partition *ep, struct slice *sp, int ns) { - struct partition *p; + struct partition p; unsigned long start, here; unsigned char *bp; int loopct = 0; @@ -33,14 +34,13 @@ read_extended_partition(int fd, struct p if (bp[510] != 0x55 || bp[511] != 0xaa) return n; - p = (struct partition *) (bp + 0x1be); - - for (i=0; i<2; i++, p++) { - if (p->nr_sects == 0 || is_extended(p->sys_type)) + for (i=0; i<2; i++) { + memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); + if (p.nr_sects == 0 || is_extended(p.sys_type)) continue; if (n < ns) { - sp[n].start = here + le32_to_cpu(p->start_sect); - sp[n].size = le32_to_cpu(p->nr_sects); + sp[n].start = here + le32_to_cpu(p.start_sect); + sp[n].size = le32_to_cpu(p.nr_sects); n++; } else { fprintf(stderr, @@ -50,10 +50,10 @@ read_extended_partition(int fd, struct p loopct = 0; } - p -= 2; - for (i=0; i<2; i++, p++) { - if(p->nr_sects != 0 && is_extended(p->sys_type)) { - here = start + le32_to_cpu(p->start_sect); + for (i=0; i<2; i++) { + memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); + if(p.nr_sects != 0 && is_extended(p.sys_type)) { + here = start + le32_to_cpu(p.start_sect); moretodo = 1; break; } @@ -69,7 +69,7 @@ is_gpt(int type) { int read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) { - struct partition *p; + struct partition p; unsigned long offset = all.start; int i, n=0; unsigned char *bp; @@ -81,32 +81,29 @@ read_dos_pt(int fd, struct slice all, st if (bp[510] != 0x55 || bp[511] != 0xaa) return -1; - p = (struct partition *) (bp + 0x1be); for (i=0; i<4; i++) { - if (is_gpt(p->sys_type)) { + memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); + if (is_gpt(p.sys_type)) { return 0; } - p++; } - p = (struct partition *) (bp + 0x1be); for (i=0; i<4; i++) { + memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); /* always add, even if zero length */ if (n < ns) { - sp[n].start = le32_to_cpu(p->start_sect); - sp[n].size = le32_to_cpu(p->nr_sects); + sp[n].start = le32_to_cpu(p.start_sect); + sp[n].size = le32_to_cpu(p.nr_sects); n++; } else { fprintf(stderr, "dos_partition: too many slices\n"); break; } - p++; } - p = (struct partition *) (bp + 0x1be); for (i=0; i<4; i++) { - if (is_extended(p->sys_type)) - n += read_extended_partition(fd, p, sp+n, ns-n); - p++; + memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); + if (is_extended(p.sys_type)) + n += read_extended_partition(fd, &p, sp+n, ns-n); } return n; } !-------------------------------------------------------------flip- Only use one loop to read all data. --- commit 1d586d3a1a998b64fa27e61777478d8735d4152a tree 4553a5ad1ef3367600b00abded4e521ce7629088 parent 6399c88650be9835b90bad91a7b6268db8db3303 author Bastian Blank <waldi@xxxxxxxxxx> Thu, 29 Sep 2005 13:06:34 +0000 committer Bastian Blank <waldi@xxxxxxxxxx> Thu, 29 Sep 2005 13:06:34 +0000 kpartx/dos.c | 37 ++++++++++++++----------------------- 1 files changed, 14 insertions(+), 23 deletions(-) diff --git a/kpartx/dos.c b/kpartx/dos.c --- a/kpartx/dos.c +++ b/kpartx/dos.c @@ -36,8 +36,14 @@ read_extended_partition(int fd, struct p for (i=0; i<2; i++) { memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); - if (p.nr_sects == 0 || is_extended(p.sys_type)) - continue; + if (is_extended(p.sys_type)) { + if (p.nr_sects) { + here = start + le32_to_cpu(p.start_sect); + moretodo = 1; + } + else + continue; + } if (n < ns) { sp[n].start = here + le32_to_cpu(p.start_sect); sp[n].size = le32_to_cpu(p.nr_sects); @@ -49,15 +55,6 @@ read_extended_partition(int fd, struct p } loopct = 0; } - - for (i=0; i<2; i++) { - memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); - if(p.nr_sects != 0 && is_extended(p.sys_type)) { - here = start + le32_to_cpu(p.start_sect); - moretodo = 1; - break; - } - } } return n; } @@ -71,7 +68,7 @@ int read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) { struct partition p; unsigned long offset = all.start; - int i, n=0; + int i, n=4; unsigned char *bp; bp = (unsigned char *)getblock(fd, offset); @@ -83,25 +80,19 @@ read_dos_pt(int fd, struct slice all, st for (i=0; i<4; i++) { memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); - if (is_gpt(p.sys_type)) { - return 0; - } } for (i=0; i<4; i++) { memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); - /* always add, even if zero length */ - if (n < ns) { - sp[n].start = le32_to_cpu(p.start_sect); - sp[n].size = le32_to_cpu(p.nr_sects); - n++; + if (is_gpt(p.sys_type)) + return 0; + if (i < ns) { + sp[i].start = le32_to_cpu(p.start_sect); + sp[i].size = le32_to_cpu(p.nr_sects); } else { fprintf(stderr, "dos_partition: too many slices\n"); break; } - } - for (i=0; i<4; i++) { - memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p)); if (is_extended(p.sys_type)) n += read_extended_partition(fd, &p, sp+n, ns-n); } !-------------------------------------------------------------flip- -- Women professionals do tend to over-compensate. -- Dr. Elizabeth Dehaver, "Where No Man Has Gone Before", stardate 1312.9.
Attachment:
signature.asc
Description: Digital signature
-- dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel