Add support for a byteswapped disklabel so that I can mount
NetBSD/sparc anita images on my i386.
This commit is contained in:
parent
fbe84585a0
commit
27ec9b9d1d
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue