[dm-devel] [PATCH] multipath-tools/kpartx - fix endianes, undefined behaviour, cleanup

Bastian Blank bastian at waldi.eu.org
Thu Sep 29 12:41:15 UTC 2005


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 at debian.org> Thu, 29 Sep 2005 12:55:36 +0000
committer Bastian Blank <waldi at debian.org> 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 at debian.org> Thu, 29 Sep 2005 13:01:45 +0000
committer Bastian Blank <waldi at debian.org> 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 at debian.org> Thu, 29 Sep 2005 13:06:34 +0000
committer Bastian Blank <waldi at debian.org> 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/dm-devel/attachments/20050929/691a8028/attachment.sig>


More information about the dm-devel mailing list