Extract common code from i386, xen, and sparc64, creating
config_handle_wedges() and read_disk_sectors(). On x86, handle_wedges() is a thin wrapper for config_handle_wedges(). Share opendisk() across architectures. Add kernel code in support of specifying a root partition by wedge name. E.g., root specifications "wedge:wd0a", "wedge:David's Root Volume" are possible. (Patches for config(1) coming soon.) In support of moving disks between architectures (esp. i386 <-> evbmips), I've written a routine convertdisklabel() that ensures that the raw partition is at RAW_DISK by following these steps: 0 If we have read a disklabel that has a RAW_PART with p_offset == 0 and p_size != 0, then use that raw partition. 1 If we have read a disklabel that has both partitions 'c' and 'd', and RAW_PART has p_offset != 0 or p_size == 0, but the other partition is suitable for a raw partition (p_offset == 0, p_size != 0), then swap the two partitions and use the new raw partition. 2 If the architecture's raw partition is 'd', and if there is no partition 'd', but there is a partition 'c' that is suitable for a raw partition, then copy partition 'c' to partition 'd'. 3 Determine the drive's last sector, using either the d_secperunit the drive reported, or by guessing (0x1fffffff). If we cannot read the drive's last sector, then fail. 4 If we have read a disklabel that has no partition slot RAW_PART, then create a partition RAW_PART. Make it span the whole drive. 5 If there are fewer than MAXPARTITIONS partitions, then "slide" the unsuitable raw partition RAW_PART, and subsequent partitions, into partition slots RAW_PART+1 and subsequent slots. Create a raw partition at RAW_PART. Make it span the whole drive. The convertdisklabel() procedure can probably stand to be simplified, but it ought to deal with all but an extraordinarily broken disklabel, now. i386: compiled and tested, sparc64: compiled, evbmips: compiled.
This commit is contained in:
parent
82cc8fc351
commit
1ee8f4a418
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: disksubr.c,v 1.12 2007/03/06 00:48:08 simonb Exp $ */
|
||||
/* $NetBSD: disksubr.c,v 1.13 2007/06/24 01:43:34 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: disksubr.c,v 1.12 2007/03/06 00:48:08 simonb Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: disksubr.c,v 1.13 2007/06/24 01:43:34 dyoung Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -54,6 +54,7 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
|
||||
struct disklabel *dlp;
|
||||
struct dkbad *bdp;
|
||||
const char *msg = NULL;
|
||||
uint32_t secperunit;
|
||||
int i;
|
||||
|
||||
/* minimal requirements for archtypal disk label */
|
||||
@ -66,19 +67,16 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
|
||||
lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
|
||||
lp->d_partitions[RAW_PART].p_offset = 0;
|
||||
|
||||
secperunit = lp->d_secperunit;
|
||||
|
||||
/* obtain buffer to probe drive with */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
|
||||
/* next, dig out disk label */
|
||||
bp->b_dev = dev;
|
||||
bp->b_blkno = LABELSECTOR;
|
||||
bp->b_cylinder = 0;
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_flags |= B_READ;
|
||||
(*strat)(bp);
|
||||
|
||||
/* if successful, locate disk label within block and validate */
|
||||
if (biowait(bp)) {
|
||||
/* Next, dig out disk label. If successful, locate disk
|
||||
* label within block and validate.
|
||||
*/
|
||||
if (disk_read_sectors(strat, lp, bp, LABELSECTOR, 1) != 0) {
|
||||
msg = "disk label read error";
|
||||
goto done;
|
||||
}
|
||||
@ -103,6 +101,9 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
|
||||
if (msg)
|
||||
goto done;
|
||||
|
||||
if ((msg = convertdisklabel(lp, strat, bp, secperunit)) != NULL)
|
||||
goto done;
|
||||
|
||||
/* obtain bad sector table if requested and present */
|
||||
if (clp && (bdp = &clp->bad) != NULL && (lp->d_flags & D_BADSECT)) {
|
||||
struct dkbad *db;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: autoconf.c,v 1.137 2007/03/04 06:00:50 christos Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.138 2007/06/24 01:43:34 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
@ -48,7 +48,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.137 2007/03/04 06:00:50 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.138 2007/06/24 01:43:34 dyoung Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_kgdb.h"
|
||||
@ -430,58 +430,9 @@ cpu_configure(void)
|
||||
(void)spl0();
|
||||
}
|
||||
|
||||
static struct vnode *
|
||||
opendisk(struct device *dv)
|
||||
{
|
||||
int bmajor, bminor;
|
||||
struct vnode *tmpvn;
|
||||
int error;
|
||||
dev_t dev;
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return NULL;
|
||||
|
||||
bminor = minor(device_unit(dv));
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* and hash the sectors.
|
||||
*/
|
||||
dev = device_is_a(dv, "dk") ? makedev(bmajor, bminor) :
|
||||
MAKEDISKDEV(bmajor, bminor, RAW_PART);
|
||||
if (bdevvp(dev, &tmpvn))
|
||||
panic("%s: can't alloc vnode for %s", __func__,
|
||||
device_xname(dv));
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("%s: can't open dev %s (%d)\n",
|
||||
__func__, device_xname(dv), error);
|
||||
vput(tmpvn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tmpvn;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_rootconf(void)
|
||||
{
|
||||
struct dkwedge_list wl;
|
||||
struct dkwedge_info *wi;
|
||||
struct vnode *vn;
|
||||
char diskname[16];
|
||||
int i, error;
|
||||
|
||||
if (booted_device == NULL) {
|
||||
printf("FATAL: boot device not found, check your firmware "
|
||||
"settings!\n");
|
||||
@ -489,37 +440,10 @@ cpu_rootconf(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((vn = opendisk(booted_device)) == NULL)
|
||||
goto nowedge;
|
||||
|
||||
wl.dkwl_bufsize = sizeof(*wi) * 16;
|
||||
wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
|
||||
error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
|
||||
VOP_CLOSE(vn, FREAD, NOCRED, 0);
|
||||
vput(vn);
|
||||
if (error)
|
||||
goto nowedge2;
|
||||
|
||||
snprintf(diskname, sizeof(diskname), "%s%c",
|
||||
device_xname(booted_device),
|
||||
booted_partition + 'a');
|
||||
|
||||
for (i = 0; i < wl.dkwl_ncopied; i++) {
|
||||
if (strcmp(wi[i].dkw_wname, diskname) == 0)
|
||||
break;
|
||||
}
|
||||
if (i == wl.dkwl_ncopied)
|
||||
goto nowedge2;
|
||||
|
||||
dkwedge_set_bootwedge(booted_device, wi[i].dkw_offset, wi[i].dkw_size);
|
||||
free(wi, M_TEMP);
|
||||
setroot(booted_wedge, 0);
|
||||
return;
|
||||
|
||||
nowedge2:
|
||||
free(wi, M_TEMP);
|
||||
nowedge:
|
||||
setroot(booted_device, booted_partition);
|
||||
if (config_handle_wedges(booted_device, booted_partition) == 0)
|
||||
setroot(booted_wedge, 0);
|
||||
else
|
||||
setroot(booted_device, booted_partition);
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: x86_autoconf.c,v 1.25 2007/03/04 06:01:09 christos Exp $ */
|
||||
/* $NetBSD: x86_autoconf.c,v 1.26 2007/06/24 01:43:34 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
@ -65,114 +65,15 @@ __KERNEL_RCSID(0, "$NetBSD");
|
||||
struct disklist *x86_alldisks;
|
||||
int x86_ndisks;
|
||||
|
||||
static struct vnode *
|
||||
opendisk(struct device *dv)
|
||||
{
|
||||
int bmajor, bminor;
|
||||
struct vnode *tmpvn;
|
||||
int error;
|
||||
dev_t dev;
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return NULL;
|
||||
|
||||
bminor = minor(device_unit(dv));
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* and hash the sectors.
|
||||
*/
|
||||
dev = device_is_a(dv, "dk") ? makedev(bmajor, bminor) :
|
||||
MAKEDISKDEV(bmajor, bminor, RAW_PART);
|
||||
if (bdevvp(dev, &tmpvn))
|
||||
panic("%s: can't alloc vnode for %s", __func__, dv->dv_xname);
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("%s: can't open dev %s (%d)\n",
|
||||
__func__, dv->dv_xname, error);
|
||||
vput(tmpvn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tmpvn;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_wedges(struct device *dv, int par)
|
||||
{
|
||||
struct dkwedge_list wl;
|
||||
struct dkwedge_info *wi;
|
||||
struct vnode *vn;
|
||||
char diskname[16];
|
||||
int i, error;
|
||||
|
||||
if ((vn = opendisk(dv)) == NULL)
|
||||
goto out;
|
||||
|
||||
wl.dkwl_bufsize = sizeof(*wi) * 16;
|
||||
wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
|
||||
|
||||
error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
|
||||
VOP_CLOSE(vn, FREAD, NOCRED, 0);
|
||||
vput(vn);
|
||||
if (error) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: List wedges returned %d\n", dv->dv_xname, error);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Returned %u(%u) wedges\n", dv->dv_xname,
|
||||
wl.dkwl_nwedges, wl.dkwl_ncopied);
|
||||
#endif
|
||||
snprintf(diskname, sizeof(diskname), "%s%c", dv->dv_xname,
|
||||
par + 'a');
|
||||
|
||||
for (i = 0; i < wl.dkwl_ncopied; i++) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Looking for %s in %s\n",
|
||||
dv->dv_xname, diskname, wi[i].dkw_wname);
|
||||
#endif
|
||||
if (strcmp(wi[i].dkw_wname, diskname) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == wl.dkwl_ncopied) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Cannot find wedge with parent %s\n",
|
||||
dv->dv_xname, diskname);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Setting boot wedge %s (%s) at %llu %llu\n",
|
||||
dv->dv_xname, wi[i].dkw_devname, wi[i].dkw_wname,
|
||||
(unsigned long long)wi[i].dkw_offset,
|
||||
(unsigned long long)wi[i].dkw_size);
|
||||
#endif
|
||||
dkwedge_set_bootwedge(dv, wi[i].dkw_offset, wi[i].dkw_size);
|
||||
free(wi, M_TEMP);
|
||||
return;
|
||||
out:
|
||||
if (config_handle_wedges(dv, par) == 0)
|
||||
return;
|
||||
booted_device = dv;
|
||||
booted_partition = par;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
is_valid_disk(struct device *dv)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: autoconf.c,v 1.23 2007/05/17 14:51:35 yamt Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.24 2007/06/24 01:43:34 dyoung Exp $ */
|
||||
/* NetBSD: autoconf.c,v 1.75 2003/12/30 12:33:22 pk Exp */
|
||||
|
||||
/*-
|
||||
@ -45,7 +45,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.23 2007/05/17 14:51:35 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.24 2007/06/24 01:43:34 dyoung Exp $");
|
||||
|
||||
#include "opt_xen.h"
|
||||
#include "opt_compat_oldboot.h"
|
||||
@ -94,7 +94,6 @@ static int match_harddisk(struct device *, struct btinfo_bootdisk *);
|
||||
static void matchbiosdisks(void);
|
||||
static void findroot(void);
|
||||
static int is_valid_disk(struct device *);
|
||||
static struct vnode *opendisk(struct device *);
|
||||
static void handle_wedges(struct device *, int);
|
||||
|
||||
struct disklist *x86_alldisks;
|
||||
@ -568,104 +567,11 @@ found:
|
||||
booted_device = dev;
|
||||
}
|
||||
|
||||
static struct vnode *
|
||||
opendisk(struct device *dv)
|
||||
{
|
||||
int bmajor;
|
||||
struct vnode *tmpvn;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* and hash the sectors.
|
||||
*/
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART), &tmpvn))
|
||||
panic("%s: can't alloc vnode for %s", __func__, dv->dv_xname);
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("%s: can't open dev %s (%d)\n",
|
||||
__func__, dv->dv_xname, error);
|
||||
vput(tmpvn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tmpvn;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_wedges(struct device *dv, int par)
|
||||
{
|
||||
struct dkwedge_list wl;
|
||||
struct dkwedge_info *wi;
|
||||
struct vnode *vn;
|
||||
char diskname[16];
|
||||
int i, error;
|
||||
|
||||
if ((vn = opendisk(dv)) == NULL)
|
||||
goto out;
|
||||
|
||||
wl.dkwl_bufsize = sizeof(*wi) * 16;
|
||||
wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
|
||||
|
||||
error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
|
||||
vput(vn);
|
||||
if (error) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: List wedges returned %d\n", dv->dv_xname, error);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Returned %u(%u) wedges\n", dv->dv_xname,
|
||||
wl.dkwl_nwedges, wl.dkwl_ncopied);
|
||||
#endif
|
||||
snprintf(diskname, sizeof(diskname), "%s%c", dv->dv_xname,
|
||||
par + 'a');
|
||||
|
||||
for (i = 0; i < wl.dkwl_ncopied; i++) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Looking for %s in %s\n",
|
||||
dv->dv_xname, diskname, wi[i].dkw_wname);
|
||||
#endif
|
||||
if (strcmp(wi[i].dkw_wname, diskname) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == wl.dkwl_ncopied) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Cannot find wedge with parent %s\n",
|
||||
dv->dv_xname, diskname);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Setting boot wedge %s (%s) at %llu %llu\n",
|
||||
dv->dv_xname, wi[i].dkw_devname, wi[i].dkw_wname,
|
||||
(unsigned long long)wi[i].dkw_offset,
|
||||
(unsigned long long)wi[i].dkw_size);
|
||||
#endif
|
||||
dkwedge_set_bootwedge(dv, wi[i].dkw_offset, wi[i].dkw_size);
|
||||
free(wi, M_TEMP);
|
||||
return;
|
||||
out:
|
||||
if (config_handle_wedges(dv, par) == 0)
|
||||
return;
|
||||
booted_device = dv;
|
||||
booted_partition = par;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dk.c,v 1.24 2007/06/16 18:11:33 christos Exp $ */
|
||||
/* $NetBSD: dk.c,v 1.25 2007/06/24 01:43:34 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.24 2007/06/16 18:11:33 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.25 2007/06/24 01:43:34 dyoung Exp $");
|
||||
|
||||
#include "opt_dkwedge.h"
|
||||
|
||||
@ -642,6 +642,47 @@ dkwedge_list(struct disk *pdk, struct dkwedge_list *dkwl, struct lwp *l)
|
||||
return (error);
|
||||
}
|
||||
|
||||
device_t
|
||||
dkwedge_find_by_wname(const char *wname)
|
||||
{
|
||||
device_t dv = NULL;
|
||||
struct dkwedge_softc *sc;
|
||||
int i;
|
||||
|
||||
(void) lockmgr(&dkwedges_lock, LK_EXCLUSIVE, NULL);
|
||||
for (i = 0; i < ndkwedges; i++) {
|
||||
if ((sc = dkwedges[i]) == NULL)
|
||||
continue;
|
||||
if (strcmp(sc->sc_wname, wname) == 0) {
|
||||
if (dv != NULL) {
|
||||
printf(
|
||||
"WARNING: double match for wedge name %s "
|
||||
"(%s, %s)\n", wname, device_xname(dv),
|
||||
device_xname(sc->sc_dev));
|
||||
continue;
|
||||
}
|
||||
dv = sc->sc_dev;
|
||||
}
|
||||
}
|
||||
(void) lockmgr(&dkwedges_lock, LK_RELEASE, NULL);
|
||||
return dv;
|
||||
}
|
||||
|
||||
void
|
||||
dkwedge_print_wnames(void)
|
||||
{
|
||||
struct dkwedge_softc *sc;
|
||||
int i;
|
||||
|
||||
(void) lockmgr(&dkwedges_lock, LK_EXCLUSIVE, NULL);
|
||||
for (i = 0; i < ndkwedges; i++) {
|
||||
if ((sc = dkwedges[i]) == NULL)
|
||||
continue;
|
||||
printf(" wedge:%s", sc->sc_wname);
|
||||
}
|
||||
(void) lockmgr(&dkwedges_lock, LK_RELEASE, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* dkwedge_set_bootwedge
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_subr.c,v 1.158 2007/06/03 07:47:50 dsl Exp $ */
|
||||
/* $NetBSD: kern_subr.c,v 1.159 2007/06/24 01:43:34 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
|
||||
@ -86,7 +86,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.158 2007/06/03 07:47:50 dsl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.159 2007/06/24 01:43:34 dyoung Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_md.h"
|
||||
@ -105,6 +105,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.158 2007/06/03 07:47:50 dsl Exp $");
|
||||
#include <sys/device.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/systrace.h>
|
||||
@ -122,6 +123,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.158 2007/06/03 07:47:50 dsl Exp $");
|
||||
static struct device *finddevice(const char *);
|
||||
static struct device *getdisk(char *, int, int, dev_t *, int);
|
||||
static struct device *parsedisk(char *, int, int, dev_t *);
|
||||
static const char *getwedgename(const char *, int);
|
||||
|
||||
/*
|
||||
* A generic linear hook.
|
||||
@ -811,7 +813,7 @@ void
|
||||
setroot(struct device *bootdv, int bootpartition)
|
||||
{
|
||||
struct device *dv;
|
||||
int len;
|
||||
int len, majdev;
|
||||
#ifdef MEMORY_DISK_HOOKS
|
||||
int i;
|
||||
#endif
|
||||
@ -1011,8 +1013,6 @@ setroot(struct device *bootdv, int bootpartition)
|
||||
}
|
||||
|
||||
} else if (rootspec == NULL) {
|
||||
int majdev;
|
||||
|
||||
/*
|
||||
* Wildcarded root; use the boot device.
|
||||
*/
|
||||
@ -1047,6 +1047,11 @@ setroot(struct device *bootdv, int bootpartition)
|
||||
goto haveroot;
|
||||
}
|
||||
|
||||
if (rootdev == NODEV &&
|
||||
device_class(dv) == DV_DISK && device_is_a(dv, "dk") &&
|
||||
(majdev = devsw_name2blk(dv->dv_xname, NULL, 0)) >= 0)
|
||||
rootdev = makedev(majdev, device_unit(dv));
|
||||
|
||||
rootdevname = devsw_blk2name(major(rootdev));
|
||||
if (rootdevname == NULL) {
|
||||
printf("unknown device major 0x%x\n", rootdev);
|
||||
@ -1152,25 +1157,27 @@ setroot(struct device *bootdv, int bootpartition)
|
||||
static struct device *
|
||||
finddevice(const char *name)
|
||||
{
|
||||
const char *wname;
|
||||
struct device *dv;
|
||||
#if defined(BOOT_FROM_MEMORY_HOOKS)
|
||||
int j;
|
||||
#endif /* BOOT_FROM_MEMORY_HOOKS */
|
||||
|
||||
if ((wname = getwedgename(name, strlen(name))) != NULL)
|
||||
return dkwedge_find_by_wname(wname);
|
||||
|
||||
#ifdef BOOT_FROM_MEMORY_HOOKS
|
||||
for (j = 0; j < NMD; j++) {
|
||||
if (strcmp(name, fakemdrootdev[j].dv_xname) == 0) {
|
||||
dv = &fakemdrootdev[j];
|
||||
return (dv);
|
||||
}
|
||||
if (strcmp(name, fakemdrootdev[j].dv_xname) == 0)
|
||||
return &fakemdrootdev[j];
|
||||
}
|
||||
#endif /* BOOT_FROM_MEMORY_HOOKS */
|
||||
|
||||
for (dv = TAILQ_FIRST(&alldevs); dv != NULL;
|
||||
dv = TAILQ_NEXT(dv, dv_list))
|
||||
TAILQ_FOREACH(dv, &alldevs, dv_list) {
|
||||
if (strcmp(dv->dv_xname, name) == 0)
|
||||
break;
|
||||
return (dv);
|
||||
}
|
||||
return dv;
|
||||
}
|
||||
|
||||
static struct device *
|
||||
@ -1198,6 +1205,7 @@ getdisk(char *str, int len, int defpart, dev_t *devp, int isdump)
|
||||
if (isdump == 0 && device_class(dv) == DV_IFNET)
|
||||
printf(" %s", dv->dv_xname);
|
||||
}
|
||||
dkwedge_print_wnames();
|
||||
if (isdump)
|
||||
printf(" none");
|
||||
#if defined(DDB)
|
||||
@ -1205,13 +1213,26 @@ getdisk(char *str, int len, int defpart, dev_t *devp, int isdump)
|
||||
#endif
|
||||
printf(" halt reboot\n");
|
||||
}
|
||||
return (dv);
|
||||
return dv;
|
||||
}
|
||||
|
||||
static const char *
|
||||
getwedgename(const char *name, int namelen)
|
||||
{
|
||||
const char *wpfx = "wedge:";
|
||||
const int wpfxlen = strlen(wpfx);
|
||||
|
||||
if (namelen < wpfxlen || strncmp(name, wpfx, wpfxlen) != 0)
|
||||
return NULL;
|
||||
|
||||
return name + wpfxlen;
|
||||
}
|
||||
|
||||
static struct device *
|
||||
parsedisk(char *str, int len, int defpart, dev_t *devp)
|
||||
{
|
||||
struct device *dv;
|
||||
const char *wname;
|
||||
char *cp, c;
|
||||
int majdev, part;
|
||||
#ifdef MEMORY_DISK_HOOKS
|
||||
@ -1231,7 +1252,13 @@ parsedisk(char *str, int len, int defpart, dev_t *devp)
|
||||
|
||||
cp = str + len - 1;
|
||||
c = *cp;
|
||||
if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
|
||||
|
||||
if ((wname = getwedgename(str, len)) != NULL) {
|
||||
if ((dv = dkwedge_find_by_wname(wname)) == NULL)
|
||||
return NULL;
|
||||
part = defpart;
|
||||
goto gotdisk;
|
||||
} else if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
|
||||
part = c - 'a';
|
||||
*cp = '\0';
|
||||
} else
|
||||
@ -1248,9 +1275,7 @@ parsedisk(char *str, int len, int defpart, dev_t *devp)
|
||||
dv = finddevice(str);
|
||||
if (dv != NULL) {
|
||||
if (device_class(dv) == DV_DISK) {
|
||||
#ifdef MEMORY_DISK_HOOKS
|
||||
gotdisk:
|
||||
#endif
|
||||
majdev = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (majdev < 0)
|
||||
panic("parsedisk");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr_autoconf.c,v 1.117 2007/03/05 20:32:45 drochner Exp $ */
|
||||
/* $NetBSD: subr_autoconf.c,v 1.118 2007/06/24 01:43:35 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 2000 Christopher G. Demetriou
|
||||
@ -77,18 +77,34 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.117 2007/03/05 20:32:45 drochner Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.118 2007/06/24 01:43:35 dyoung Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kauth.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <sys/buf.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/lockf.h>
|
||||
|
||||
#include <sys/disk.h>
|
||||
|
||||
#include <machine/limits.h>
|
||||
|
||||
#include "opt_userconf.h"
|
||||
@ -187,6 +203,112 @@ static int config_initialized; /* config_init() has been called. */
|
||||
|
||||
static int config_do_twiddle;
|
||||
|
||||
struct vnode *
|
||||
opendisk(struct device *dv)
|
||||
{
|
||||
int bmajor, bminor;
|
||||
struct vnode *tmpvn;
|
||||
int error;
|
||||
dev_t dev;
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return NULL;
|
||||
|
||||
bminor = minor(device_unit(dv));
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* and hash the sectors.
|
||||
*/
|
||||
dev = device_is_a(dv, "dk") ? makedev(bmajor, bminor) :
|
||||
MAKEDISKDEV(bmajor, bminor, RAW_PART);
|
||||
if (bdevvp(dev, &tmpvn))
|
||||
panic("%s: can't alloc vnode for %s", __func__,
|
||||
device_xname(dv));
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("%s: can't open dev %s (%d)\n",
|
||||
__func__, device_xname(dv), error);
|
||||
vput(tmpvn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tmpvn;
|
||||
}
|
||||
|
||||
int
|
||||
config_handle_wedges(struct device *dv, int par)
|
||||
{
|
||||
struct dkwedge_list wl;
|
||||
struct dkwedge_info *wi;
|
||||
struct vnode *vn;
|
||||
char diskname[16];
|
||||
int i, error;
|
||||
|
||||
if ((vn = opendisk(dv)) == NULL)
|
||||
return -1;
|
||||
|
||||
wl.dkwl_bufsize = sizeof(*wi) * 16;
|
||||
wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
|
||||
|
||||
error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
|
||||
VOP_CLOSE(vn, FREAD, NOCRED, 0);
|
||||
vput(vn);
|
||||
if (error) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: List wedges returned %d\n",
|
||||
device_xname(dv), error);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Returned %u(%u) wedges\n", device_xname(dv),
|
||||
wl.dkwl_nwedges, wl.dkwl_ncopied);
|
||||
#endif
|
||||
snprintf(diskname, sizeof(diskname), "%s%c", device_xname(dv),
|
||||
par + 'a');
|
||||
|
||||
for (i = 0; i < wl.dkwl_ncopied; i++) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Looking for %s in %s\n",
|
||||
device_xname(dv), diskname, wi[i].dkw_wname);
|
||||
#endif
|
||||
if (strcmp(wi[i].dkw_wname, diskname) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == wl.dkwl_ncopied) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Cannot find wedge with parent %s\n",
|
||||
device_xname(dv), diskname);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Setting boot wedge %s (%s) at %llu %llu\n",
|
||||
device_xname(dv), wi[i].dkw_devname, wi[i].dkw_wname,
|
||||
(unsigned long long)wi[i].dkw_offset,
|
||||
(unsigned long long)wi[i].dkw_size);
|
||||
#endif
|
||||
dkwedge_set_bootwedge(dv, wi[i].dkw_offset, wi[i].dkw_size);
|
||||
free(wi, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the autoconfiguration data structures. Normally this
|
||||
* is done by configure(), but some platforms need to do this very
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr_disk.c,v 1.85 2007/03/04 06:03:07 christos Exp $ */
|
||||
/* $NetBSD: subr_disk.c,v 1.86 2007/06/24 01:43:35 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -74,7 +74,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.85 2007/03/04 06:03:07 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.86 2007/06/24 01:43:35 dyoung Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -266,6 +266,7 @@ disk_detach(struct disk *diskp)
|
||||
{
|
||||
|
||||
(void) lockmgr(&diskp->dk_openlock, LK_DRAIN, NULL);
|
||||
(void) lockmgr(&diskp->dk_rawlock, LK_DRAIN, NULL);
|
||||
disk_detach0(diskp);
|
||||
}
|
||||
|
||||
@ -430,6 +431,81 @@ bad:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
disk_read_sectors(void (*strat)(struct buf *), const struct disklabel *lp,
|
||||
struct buf *bp, unsigned int sector, int count)
|
||||
{
|
||||
bp->b_blkno = sector;
|
||||
bp->b_bcount = count * lp->d_secsize;
|
||||
bp->b_flags = (bp->b_flags & ~(B_WRITE | B_DONE)) | B_READ;
|
||||
bp->b_cylinder = sector / lp->d_secpercyl;
|
||||
(*strat)(bp);
|
||||
return biowait(bp);
|
||||
}
|
||||
|
||||
const char *
|
||||
convertdisklabel(struct disklabel *lp, void (*strat)(struct buf *),
|
||||
struct buf *bp, uint32_t secperunit)
|
||||
{
|
||||
struct partition rp, *altp, *p;
|
||||
int geom_ok;
|
||||
|
||||
memset(&rp, 0, sizeof(rp));
|
||||
rp.p_size = secperunit;
|
||||
rp.p_fstype = FS_UNUSED;
|
||||
|
||||
/* If we can seek to d_secperunit - 1, believe the disk geometry. */
|
||||
if (secperunit != 0 &&
|
||||
disk_read_sectors(strat, lp, bp, secperunit - 1, 1) == 0)
|
||||
geom_ok = 1;
|
||||
else
|
||||
geom_ok = 0;
|
||||
|
||||
#if 0
|
||||
printf("%s: secperunit (%" PRIu32 ") %s\n", __func__,
|
||||
secperunit, geom_ok ? "ok" : "not ok");
|
||||
#endif
|
||||
|
||||
p = &lp->d_partitions[RAW_PART];
|
||||
if (RAW_PART == 'c' - 'a')
|
||||
altp = &lp->d_partitions['d' - 'a'];
|
||||
else
|
||||
altp = &lp->d_partitions['c' - 'a'];
|
||||
|
||||
if (lp->d_npartitions > RAW_PART && p->p_offset == 0 && p->p_size != 0)
|
||||
; /* already a raw partition */
|
||||
else if (lp->d_npartitions > MAX('c', 'd') - 'a' &&
|
||||
altp->p_offset == 0 && altp->p_size != 0) {
|
||||
/* alternate partition ('c' or 'd') is suitable for raw slot,
|
||||
* swap with 'd' or 'c'.
|
||||
*/
|
||||
rp = *p;
|
||||
*p = *altp;
|
||||
*altp = rp;
|
||||
} else if (lp->d_npartitions <= RAW_PART &&
|
||||
lp->d_npartitions > 'c' - 'a') {
|
||||
/* No raw partition is present, but the alternate is present.
|
||||
* Copy alternate to raw partition.
|
||||
*/
|
||||
lp->d_npartitions = RAW_PART + 1;
|
||||
*p = *altp;
|
||||
} else if (!geom_ok)
|
||||
return "no raw partition and disk reports bad geometry";
|
||||
else if (lp->d_npartitions <= RAW_PART) {
|
||||
memset(&lp->d_partitions[lp->d_npartitions], 0,
|
||||
sizeof(struct partition) * (RAW_PART - lp->d_npartitions));
|
||||
*p = rp;
|
||||
lp->d_npartitions = RAW_PART + 1;
|
||||
} else if (lp->d_npartitions < MAXPARTITIONS) {
|
||||
memmove(p + 1, p,
|
||||
sizeof(struct partition) * (lp->d_npartitions - RAW_PART));
|
||||
*p = rp;
|
||||
lp->d_npartitions++;
|
||||
} else
|
||||
return "no raw partition and partition table is full";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* disk_ioctl --
|
||||
* Generic disk ioctl handling.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr_disk_mbr.c,v 1.27 2007/06/14 17:18:40 dyoung Exp $ */
|
||||
/* $NetBSD: subr_disk_mbr.c,v 1.28 2007/06/24 01:43:35 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
|
||||
@ -54,7 +54,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_disk_mbr.c,v 1.27 2007/06/14 17:18:40 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_disk_mbr.c,v 1.28 2007/06/24 01:43:35 dyoung Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -93,6 +93,7 @@ typedef struct mbr_args {
|
||||
int found_mbr; /* set if disk has a valid mbr */
|
||||
uint label_sector; /* where we found the label */
|
||||
int action;
|
||||
uint32_t secperunit;
|
||||
#define READ_LABEL 1
|
||||
#define UPDATE_LABEL 2
|
||||
#define WRITE_LABEL 3
|
||||
@ -105,15 +106,9 @@ static int write_netbsd_label(mbr_args_t *, mbr_partition_t *, int, uint);
|
||||
static int
|
||||
read_sector(mbr_args_t *a, uint sector, int count)
|
||||
{
|
||||
struct buf *bp = a->bp;
|
||||
int error;
|
||||
|
||||
bp->b_blkno = sector;
|
||||
bp->b_bcount = count * a->lp->d_secsize;
|
||||
bp->b_flags = (bp->b_flags & ~(B_WRITE | B_DONE)) | B_READ;
|
||||
bp->b_cylinder = sector / a->lp->d_secpercyl;
|
||||
(*a->strat)(bp);
|
||||
error = biowait(bp);
|
||||
error = disk_read_sectors(a->strat, a->lp, a->bp, sector, count);
|
||||
if (error != 0)
|
||||
a->error = error;
|
||||
return error;
|
||||
@ -265,6 +260,7 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
|
||||
lp->d_secsize = DEV_BSIZE;
|
||||
if (lp->d_secperunit == 0)
|
||||
lp->d_secperunit = 0x1fffffff;
|
||||
a.secperunit = lp->d_secperunit;
|
||||
lp->d_npartitions = RAW_PART + 1;
|
||||
for (i = 0; i < RAW_PART; i++) {
|
||||
lp->d_partitions[i].p_size = 0;
|
||||
@ -459,6 +455,9 @@ validate_label(mbr_args_t *a, uint label_sector)
|
||||
switch (a->action) {
|
||||
case READ_LABEL:
|
||||
*a->lp = *dlp;
|
||||
if ((a->msg = convertdisklabel(a->lp, a->strat, a->bp,
|
||||
a->secperunit)) != NULL)
|
||||
return SCAN_ERROR;
|
||||
a->label_sector = label_sector;
|
||||
return SCAN_FOUND;
|
||||
case UPDATE_LABEL:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: device.h,v 1.94 2007/03/05 20:32:43 drochner Exp $ */
|
||||
/* $NetBSD: device.h,v 1.95 2007/06/24 01:43:35 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 2000 Christopher G. Demetriou
|
||||
@ -307,6 +307,9 @@ extern int booted_partition; /* or the partition on that device */
|
||||
|
||||
extern volatile int config_pending; /* semaphore for mountroot */
|
||||
|
||||
struct vnode *opendisk(struct device *);
|
||||
int config_handle_wedges(struct device *, int);
|
||||
|
||||
void config_init(void);
|
||||
void configure(void);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: disk.h,v 1.43 2007/03/04 06:03:40 christos Exp $ */
|
||||
/* $NetBSD: disk.h,v 1.44 2007/06/24 01:43:35 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 2004 The NetBSD Foundation, Inc.
|
||||
@ -86,6 +86,7 @@
|
||||
* Disk device structures.
|
||||
*/
|
||||
|
||||
#include <sys/device.h>
|
||||
#include <sys/dkio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
@ -496,7 +497,6 @@ struct disk_strategy {
|
||||
#ifdef _KERNEL
|
||||
extern int disk_count; /* number of disks in global disklist */
|
||||
|
||||
struct device;
|
||||
struct proc;
|
||||
|
||||
void disk_attach(struct disk *);
|
||||
@ -515,8 +515,10 @@ int dkwedge_del(struct dkwedge_info *);
|
||||
void dkwedge_delall(struct disk *);
|
||||
int dkwedge_list(struct disk *, struct dkwedge_list *, struct lwp *);
|
||||
void dkwedge_discover(struct disk *);
|
||||
void dkwedge_set_bootwedge(struct device *, daddr_t, uint64_t);
|
||||
void dkwedge_set_bootwedge(device_t, daddr_t, uint64_t);
|
||||
int dkwedge_read(struct disk *, struct vnode *, daddr_t, void *, size_t);
|
||||
device_t dkwedge_find_by_wname(const char *);
|
||||
void dkwedge_print_wnames(void);
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_DISK_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: disklabel.h,v 1.99 2007/03/10 16:42:04 dsl Exp $ */
|
||||
/* $NetBSD: disklabel.h,v 1.100 2007/06/24 01:43:35 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1988, 1993
|
||||
@ -433,6 +433,8 @@ struct partinfo {
|
||||
|
||||
struct disk;
|
||||
|
||||
int disk_read_sectors(void (*)(struct buf *), const struct disklabel *,
|
||||
struct buf *, unsigned int, int);
|
||||
void diskerr(const struct buf *, const char *, const char *, int,
|
||||
int, const struct disklabel *);
|
||||
u_int dkcksum(struct disklabel *);
|
||||
@ -443,6 +445,8 @@ const char *readdisklabel(dev_t, void (*)(struct buf *),
|
||||
struct disklabel *, struct cpu_disklabel *);
|
||||
int writedisklabel(dev_t, void (*)(struct buf *), struct disklabel *,
|
||||
struct cpu_disklabel *);
|
||||
const char *convertdisklabel(struct disklabel *, void (*)(struct buf *),
|
||||
struct buf *, uint32_t);
|
||||
int bounds_check_with_label(struct disk *, struct buf *, int);
|
||||
int bounds_check_with_mediasize(struct buf *, int, uint64_t);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user