Add support for a byteswapped disklabel so that I can mount

NetBSD/sparc anita images on my i386.
This commit is contained in:
pooka 2011-02-22 15:42:15 +00:00
parent fbe84585a0
commit 27ec9b9d1d
3 changed files with 54 additions and 17 deletions

View File

@ -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 @@ ukfs_part_probe(char *devpath, struct ukfs_part **partp)
*(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 @@ ukfs_part_probe(char *devpath, struct ukfs_part **partp)
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 @@ ukfs_part_probe(char *devpath, struct ukfs_part **partp)
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;
}

View File

@ -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 @@ sanity:
*/
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);
}

View File

@ -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 @@ struct ukfs__disklabel {
} 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_ */