Module Name:    src
Committed By:   pooka
Date:           Tue Feb 22 15:42:15 UTC 2011

Modified Files:
        src/lib/libukfs: ukfs.c ukfs_disklabel.c ukfs_int_disklabel.h

Log Message:
Add support for a byteswapped disklabel so that I can mount
NetBSD/sparc anita images on my i386.


To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/lib/libukfs/ukfs.c
cvs rdiff -u -r1.2 -r1.3 src/lib/libukfs/ukfs_disklabel.c \
    src/lib/libukfs/ukfs_int_disklabel.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libukfs/ukfs.c
diff -u src/lib/libukfs/ukfs.c:1.56 src/lib/libukfs/ukfs.c:1.57
--- src/lib/libukfs/ukfs.c:1.56	Sun Jan  2 13:01:45 2011
+++ src/lib/libukfs/ukfs.c	Tue Feb 22 15:42:15 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ukfs.c,v 1.56 2011/01/02 13:01:45 pooka Exp $	*/
+/*	$NetBSD: ukfs.c,v 1.57 2011/02/22 15:42:15 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007, 2008, 2009  Antti Kantee.  All Rights Reserved.
@@ -246,9 +246,11 @@
 		    *(MAGICADJ_DISKLABEL(p,0)) < 'a' + UKFS_MAXPARTITIONS) {
 			struct ukfs__disklabel dl;
 			struct ukfs__partition *pp;
+			int imswapped;
 			char buf[65536];
 			char labelchar = *(MAGICADJ_DISKLABEL(p,0));
 			int partition = labelchar - 'a';
+			uint32_t poffset, psize;
 
 			*p = '\0';
 			devfd = open(devpath, O_RDONLY);
@@ -263,7 +265,8 @@
 				goto out;
 			}
 
-			if (ukfs__disklabel_scan(&dl, buf, sizeof(buf)) != 0) {
+			if (ukfs__disklabel_scan(&dl, &imswapped,
+			    buf, sizeof(buf)) != 0) {
 				error = ENOENT;
 				goto out;
 			}
@@ -276,8 +279,15 @@
 			pp = &dl.d_partitions[partition];
 			part->part_type = UKFS_PART_DISKLABEL;
 			part->part_labelchar = labelchar;
-			part->part_devoff = pp->p_offset << DEV_BSHIFT;
-			part->part_devsize = pp->p_size << DEV_BSHIFT;
+			if (imswapped) {
+				poffset = bswap32(pp->p_offset);
+				psize = bswap32(pp->p_size);
+			} else {
+				poffset = pp->p_offset;
+				psize = pp->p_size;
+			}
+			part->part_devoff = poffset << DEV_BSHIFT;
+			part->part_devsize = psize << DEV_BSHIFT;
 		} else {
 			error = EINVAL;
 		}

Index: src/lib/libukfs/ukfs_disklabel.c
diff -u src/lib/libukfs/ukfs_disklabel.c:1.2 src/lib/libukfs/ukfs_disklabel.c:1.3
--- src/lib/libukfs/ukfs_disklabel.c:1.2	Thu Dec  3 14:23:49 2009
+++ src/lib/libukfs/ukfs_disklabel.c	Tue Feb 22 15:42:15 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ukfs_disklabel.c,v 1.2 2009/12/03 14:23:49 pooka Exp $	*/
+/*	$NetBSD: ukfs_disklabel.c,v 1.3 2011/02/22 15:42:15 pooka Exp $	*/
 
 /*
  * Local copies of libutil disklabel routines.  This uncouples libukfs
@@ -50,27 +50,42 @@
 #define SCAN_INCR	4
 
 int
-ukfs__disklabel_scan(struct ukfs__disklabel *lp, char *buf, size_t buflen)
+ukfs__disklabel_scan(struct ukfs__disklabel *lp, int *isswapped,
+	char *buf, size_t buflen)
 {
-	size_t	i;
+	size_t i;
+	int imswapped;
+	uint16_t npart;
 
 	/* scan for the correct magic numbers. */
 
 	for (i=0; i <= buflen - sizeof(*lp); i += SCAN_INCR) {
 		memcpy(lp, buf + i, sizeof(*lp));
 		if (lp->d_magic == UKFS_DISKMAGIC &&
-		    lp->d_magic2 == UKFS_DISKMAGIC)
+		    lp->d_magic2 == UKFS_DISKMAGIC) {
+			imswapped = 0;
 			goto sanity;
+		}
+		if (lp->d_magic == bswap32(UKFS_DISKMAGIC) &&
+		    lp->d_magic2 == bswap32(UKFS_DISKMAGIC)) {
+			imswapped = 1;
+			goto sanity;
+		}
 	}
 
 	return 1;
 
 sanity:
+	if (imswapped)
+		npart = bswap16(lp->d_npartitions);
+	else
+		npart = lp->d_npartitions;
 	/* we've found something, let's sanity check it */
-	if (lp->d_npartitions > UKFS_MAXPARTITIONS
-	    || ukfs__disklabel_dkcksum(lp))
+	if (npart > UKFS_MAXPARTITIONS
+	    || ukfs__disklabel_dkcksum(lp, imswapped))
 		return 1;
 
+	*isswapped = imswapped;
 	return 0;
 }
 
@@ -110,15 +125,26 @@
  */
 
 uint16_t
-ukfs__disklabel_dkcksum(struct ukfs__disklabel *lp)
+ukfs__disklabel_dkcksum(struct ukfs__disklabel *lp, int imswapped)
 {
 	uint16_t *start, *end;
 	uint16_t sum;
+	uint16_t npart;
+
+	if (imswapped)
+		npart = bswap16(lp->d_npartitions);
+	else
+		npart = lp->d_npartitions;
 
 	sum = 0;
 	start = (uint16_t *)(void *)lp;
-	end = (uint16_t *)(void *)&lp->d_partitions[lp->d_npartitions];
-	while (start < end)
-		sum ^= *start++;
+	end = (uint16_t *)(void *)&lp->d_partitions[npart];
+	while (start < end) {
+		if (imswapped)
+			sum ^= bswap16(*start);
+		else
+			sum ^= *start;
+		start++;
+	}
 	return (sum);
 }
Index: src/lib/libukfs/ukfs_int_disklabel.h
diff -u src/lib/libukfs/ukfs_int_disklabel.h:1.2 src/lib/libukfs/ukfs_int_disklabel.h:1.3
--- src/lib/libukfs/ukfs_int_disklabel.h:1.2	Thu Dec  3 14:23:49 2009
+++ src/lib/libukfs/ukfs_int_disklabel.h	Tue Feb 22 15:42:15 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ukfs_int_disklabel.h,v 1.2 2009/12/03 14:23:49 pooka Exp $	*/
+/*	$NetBSD: ukfs_int_disklabel.h,v 1.3 2011/02/22 15:42:15 pooka Exp $	*/
 
 /*
  * Modified copy of disklabel.h so that ukfs doesn't have to depend
@@ -151,7 +151,8 @@
 	} d_partitions[UKFS_MAXPARTITIONS];	/* actually may be more */
 };
 
-uint16_t        ukfs__disklabel_dkcksum(struct ukfs__disklabel *);
-int             ukfs__disklabel_scan(struct ukfs__disklabel *, char *, size_t);
+uint16_t        ukfs__disklabel_dkcksum(struct ukfs__disklabel *, int);
+int             ukfs__disklabel_scan(struct ukfs__disklabel *, int *,
+				     char *, size_t);
 
 #endif /* !LIB_UKFS_DISKLABEL_H_ */

Reply via email to