Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libukfs Add support for a byteswapped disklabel so that ...



details:   https://anonhg.NetBSD.org/src/rev/beaf8c891adc
branches:  trunk
changeset: 762530:beaf8c891adc
user:      pooka <pooka%NetBSD.org@localhost>
date:      Tue Feb 22 15:42:15 2011 +0000

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

diffstat:

 lib/libukfs/ukfs.c               |  18 ++++++++++++---
 lib/libukfs/ukfs_disklabel.c     |  46 +++++++++++++++++++++++++++++++--------
 lib/libukfs/ukfs_int_disklabel.h |   7 +++--
 3 files changed, 54 insertions(+), 17 deletions(-)

diffs (157 lines):

diff -r 4143f6d3bff2 -r beaf8c891adc lib/libukfs/ukfs.c
--- a/lib/libukfs/ukfs.c        Tue Feb 22 15:03:30 2011 +0000
+++ b/lib/libukfs/ukfs.c        Tue Feb 22 15:42:15 2011 +0000
@@ -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;
                }
diff -r 4143f6d3bff2 -r beaf8c891adc lib/libukfs/ukfs_disklabel.c
--- a/lib/libukfs/ukfs_disklabel.c      Tue Feb 22 15:03:30 2011 +0000
+++ b/lib/libukfs/ukfs_disklabel.c      Tue Feb 22 15:42:15 2011 +0000
@@ -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);
 }
diff -r 4143f6d3bff2 -r beaf8c891adc lib/libukfs/ukfs_int_disklabel.h
--- a/lib/libukfs/ukfs_int_disklabel.h  Tue Feb 22 15:03:30 2011 +0000
+++ b/lib/libukfs/ukfs_int_disklabel.h  Tue Feb 22 15:42:15 2011 +0000
@@ -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_ */



Home | Main Index | Thread Index | Old Index