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_ */