Reduce code duplication in validate_label(). Extract some lengthy

code to give it 8 more columns of horizontal space, creating
addwedges() in this way.
This commit is contained in:
dyoung 2007-06-09 02:10:30 +00:00
parent d44c1c6985
commit 48beaaeef0
1 changed files with 81 additions and 88 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dkwedge_bsdlabel.c,v 1.13 2007/04/08 09:36:31 scw Exp $ */
/* $NetBSD: dkwedge_bsdlabel.c,v 1.14 2007/06/09 02:10:30 dyoung Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@ -86,7 +86,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dkwedge_bsdlabel.c,v 1.13 2007/04/08 09:36:31 scw Exp $");
__KERNEL_RCSID(0, "$NetBSD: dkwedge_bsdlabel.c,v 1.14 2007/06/09 02:10:30 dyoung Exp $");
#include <sys/param.h>
#ifdef _KERNEL
@ -222,103 +222,30 @@ swap_disklabel(struct disklabel *lp)
#undef SWAP32
}
static int
validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset)
/*
* Add wedges for a valid NetBSD disklabel.
*/
static void
addwedges(const mbr_args_t *a, const struct disklabel *lp)
{
struct disklabel *lp;
void *lp_lim;
int i, error;
u_int checksum;
int error, i;
error = dkwedge_read(a->pdk, a->vp, label_sector, a->buf, DEV_BSIZE);
if (error) {
aprint_error("%s: unable to read BSD disklabel @ %" PRId64
", error = %d\n", a->pdk->dk_name, label_sector, error);
a->error = error;
return (SCAN_ERROR);
}
/*
* We ignore label_offset; this seems to have not been used
* consistently in the old code, requiring us to do the search
* in the sector.
*/
lp = a->buf;
lp_lim = (char *)a->buf + DEV_BSIZE - DISKLABEL_MINSIZE;
for (;; lp = (void *)((char *)lp + sizeof(uint32_t))) {
if ((char *)lp > (char *)lp_lim)
return (SCAN_CONTINUE);
label_offset = (size_t)((char *)lp - (char *)a->buf);
if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
if (lp->d_magic == bswap32(DISKMAGIC) &&
lp->d_magic2 == bswap32(DISKMAGIC)) {
/*
* Label is in the other byte order; validate
* its length, then byte-swap it.
*/
if ((char *)lp +
DISKLABEL_SIZE(bswap16(lp->d_npartitions)) >
(char *)a->buf + DEV_BSIZE) {
aprint_error("%s: BSD disklabel @ "
"%" PRId64
"+%zd has bogus partition "
"count (%u)\n", a->pdk->dk_name,
label_sector, label_offset,
bswap16(lp->d_npartitions));
continue;
}
checksum = dkcksum_sized(lp,
bswap16(lp->d_npartitions));
swap_disklabel(lp);
} else
continue;
} else {
/*
* Validate the disklabel length.
*/
if ((char *)lp + DISKLABEL_SIZE(lp->d_npartitions) >
(char *)a->buf + DEV_BSIZE) {
aprint_error("%s: BSD disklabel @ %" PRId64
"+%zd has bogus partition count (%u)\n",
a->pdk->dk_name, label_sector,
label_offset, lp->d_npartitions);
continue;
}
checksum = dkcksum(lp);
}
/*
* Disklabel is now in the right order and we have validated
* the partition count, checksum it as the final check.
*/
if (checksum != 0) {
aprint_error("%s: BSD disklabel @ %" PRId64
"+%zd has bad checksum\n", a->pdk->dk_name,
label_sector, label_offset);
continue;
}
/*
* Ok, we have a valid NetBSD disklabel, add wedges for it.
*/
for (i = 0; i < lp->d_npartitions; i++) {
struct dkwedge_info dkw;
struct partition *p;
const struct partition *p;
const char *ptype;
p = &lp->d_partitions[i];
if (p->p_fstype == FS_UNUSED)
continue;
if ((ptype =
bsdlabel_fstype_to_str(p->p_fstype)) == NULL) {
if ((ptype = bsdlabel_fstype_to_str(p->p_fstype)) == NULL) {
/*
* XXX Should probably just add these...
* XXX maybe just have an empty ptype?
*/
aprint_verbose("%s: skipping partition %d, "
"type %d\n", a->pdk->dk_name, i,
p->p_fstype);
aprint_verbose("%s: skipping partition %d, type %d\n",
a->pdk->dk_name, i, p->p_fstype);
continue;
}
strcpy(dkw.dkw_ptype, ptype);
@ -344,6 +271,72 @@ validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset)
"%d type %d\n", a->pdk->dk_name, error,
i, p->p_fstype);
}
}
static int
validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset)
{
struct disklabel *lp;
void *lp_lim;
int error, swapped;
uint16_t npartitions;
error = dkwedge_read(a->pdk, a->vp, label_sector, a->buf, DEV_BSIZE);
if (error) {
aprint_error("%s: unable to read BSD disklabel @ %" PRId64
", error = %d\n", a->pdk->dk_name, label_sector, error);
a->error = error;
return (SCAN_ERROR);
}
/*
* We ignore label_offset; this seems to have not been used
* consistently in the old code, requiring us to do the search
* in the sector.
*/
lp = a->buf;
lp_lim = (char *)a->buf + DEV_BSIZE - DISKLABEL_MINSIZE;
for (;; lp = (void *)((char *)lp + sizeof(uint32_t))) {
if ((char *)lp > (char *)lp_lim)
return (SCAN_CONTINUE);
label_offset = (size_t)((char *)lp - (char *)a->buf);
if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
if (lp->d_magic != bswap32(DISKMAGIC) ||
lp->d_magic2 != bswap32(DISKMAGIC))
continue;
/* Label is in the other byte order. */
swapped = 1;
} else
swapped = 0;
npartitions = (swapped) ? bswap16(lp->d_npartitions)
: lp->d_npartitions;
/* Validate label length. */
if ((char *)lp + DISKLABEL_SIZE(npartitions) >
(char *)a->buf + DEV_BSIZE) {
aprint_error("%s: BSD disklabel @ "
"%" PRId64 "+%zd has bogus partition count (%u)\n",
a->pdk->dk_name, label_sector, label_offset,
npartitions);
continue;
}
/*
* We have validated the partition count. Checksum it.
* Note that we purposefully checksum before swapping
* the byte order.
*/
if (dkcksum_sized(lp, npartitions) != 0) {
aprint_error("%s: BSD disklabel @ %" PRId64
"+%zd has bad checksum\n", a->pdk->dk_name,
label_sector, label_offset);
continue;
}
/* Put the disklabel in the right order. */
if (swapped)
swap_disklabel(lp);
addwedges(a, lp);
return (SCAN_FOUND);
}
}