NO_GEOM cleanup: retire to attic.
This commit is contained in:
parent
c9834aa961
commit
c5cab5b2fa
@ -1,301 +0,0 @@
|
||||
#ifdef NO_GEOM
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
dev_t
|
||||
dkmodpart(dev_t dev, int part)
|
||||
{
|
||||
return (makedev(major(dev), (minor(dev) & ~7) | part));
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to read a disk label from a device using the indicated strategy
|
||||
* routine. The label must be partly set up before this: secpercyl, secsize
|
||||
* and anything required in the strategy routine (e.g., dummy bounds for the
|
||||
* partition containing the label) must be filled in before calling us.
|
||||
* Returns NULL on success and an error string on failure.
|
||||
*/
|
||||
char *
|
||||
readdisklabel(dev, lp)
|
||||
dev_t dev;
|
||||
register struct disklabel *lp;
|
||||
{
|
||||
register struct buf *bp;
|
||||
struct disklabel *dlp;
|
||||
char *msg = NULL;
|
||||
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
bp->b_dev = dev;
|
||||
bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE);
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_flags &= ~B_INVAL;
|
||||
bp->b_iocmd = BIO_READ;
|
||||
DEV_STRATEGY(bp);
|
||||
if (bufwait(bp))
|
||||
msg = "I/O error";
|
||||
else if (bp->b_resid != 0)
|
||||
msg = "disk too small for a label";
|
||||
else for (dlp = (struct disklabel *)bp->b_data;
|
||||
dlp <= (struct disklabel *)((char *)bp->b_data +
|
||||
lp->d_secsize - sizeof(*dlp));
|
||||
dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
|
||||
if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
|
||||
if (msg == NULL)
|
||||
msg = "no disk label";
|
||||
} else if (dlp->d_npartitions > MAXPARTITIONS ||
|
||||
dkcksum(dlp) != 0)
|
||||
msg = "disk label corrupted";
|
||||
else {
|
||||
*lp = *dlp;
|
||||
msg = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bp->b_flags |= B_INVAL | B_AGE;
|
||||
brelse(bp);
|
||||
return (msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check new disk label for sensibility before setting it.
|
||||
*/
|
||||
int
|
||||
setdisklabel(olp, nlp, openmask)
|
||||
register struct disklabel *olp, *nlp;
|
||||
u_long openmask;
|
||||
{
|
||||
register int i;
|
||||
register struct partition *opp, *npp;
|
||||
|
||||
/*
|
||||
* Check it is actually a disklabel we are looking at.
|
||||
*/
|
||||
if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
|
||||
dkcksum(nlp) != 0)
|
||||
return (EINVAL);
|
||||
/*
|
||||
* For each partition that we think is open,
|
||||
*/
|
||||
while ((i = ffs((long)openmask)) != 0) {
|
||||
i--;
|
||||
/*
|
||||
* Check it is not changing....
|
||||
*/
|
||||
openmask &= ~(1 << i);
|
||||
if (nlp->d_npartitions <= i)
|
||||
return (EBUSY);
|
||||
opp = &olp->d_partitions[i];
|
||||
npp = &nlp->d_partitions[i];
|
||||
if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
|
||||
return (EBUSY);
|
||||
/*
|
||||
* Copy internally-set partition information
|
||||
* if new label doesn't include it. XXX
|
||||
* (If we are using it then we had better stay the same type)
|
||||
* This is possibly dubious, as someone else noted (XXX)
|
||||
*/
|
||||
if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
|
||||
npp->p_fstype = opp->p_fstype;
|
||||
npp->p_fsize = opp->p_fsize;
|
||||
npp->p_frag = opp->p_frag;
|
||||
npp->p_cpg = opp->p_cpg;
|
||||
}
|
||||
}
|
||||
nlp->d_checksum = 0;
|
||||
nlp->d_checksum = dkcksum(nlp);
|
||||
*olp = *nlp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write disk label back to device after modification.
|
||||
*/
|
||||
int
|
||||
writedisklabel(dev, lp)
|
||||
dev_t dev;
|
||||
register struct disklabel *lp;
|
||||
{
|
||||
struct buf *bp;
|
||||
struct disklabel *dlp;
|
||||
int error = 0;
|
||||
|
||||
if (lp->d_partitions[RAW_PART].p_offset != 0)
|
||||
return (EXDEV); /* not quite right */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
bp->b_dev = dkmodpart(dev, RAW_PART);
|
||||
bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE);
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
#if 1
|
||||
/*
|
||||
* We read the label first to see if it's there,
|
||||
* in which case we will put ours at the same offset into the block..
|
||||
* (I think this is stupid [Julian])
|
||||
* Note that you can't write a label out over a corrupted label!
|
||||
* (also stupid.. how do you write the first one? by raw writes?)
|
||||
*/
|
||||
bp->b_flags &= ~B_INVAL;
|
||||
bp->b_iocmd = BIO_READ;
|
||||
DEV_STRATEGY(bp);
|
||||
error = bufwait(bp);
|
||||
if (error)
|
||||
goto done;
|
||||
if (bp->b_resid != 0) {
|
||||
error = ENOSPC;
|
||||
goto done;
|
||||
}
|
||||
for (dlp = (struct disklabel *)bp->b_data;
|
||||
dlp <= (struct disklabel *)
|
||||
((char *)bp->b_data + lp->d_secsize - sizeof(*dlp));
|
||||
dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
|
||||
if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
|
||||
dkcksum(dlp) == 0) {
|
||||
*dlp = *lp;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
bp->b_iocmd = BIO_WRITE;
|
||||
#ifdef __alpha__
|
||||
alpha_fix_srm_checksum(bp);
|
||||
#endif
|
||||
DEV_STRATEGY(bp);
|
||||
error = bufwait(bp);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
error = ESRCH;
|
||||
done:
|
||||
#else
|
||||
bzero(bp->b_data, lp->d_secsize);
|
||||
dlp = (struct disklabel *)bp->b_data;
|
||||
*dlp = *lp;
|
||||
bp->b_flags &= ~B_INVAL;
|
||||
bp->b_iocmd = BIO_WRITE;
|
||||
DEV_STRATEGY(bp);
|
||||
error = bufwait(bp);
|
||||
#endif
|
||||
bp->b_flags |= B_INVAL | B_AGE;
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the size of the transfer, and make sure it is
|
||||
* within the boundaries of the partition. Adjust transfer
|
||||
* if needed, and signal errors or early completion.
|
||||
*/
|
||||
int
|
||||
bounds_check_with_label(struct bio *bp, struct disklabel *lp, int wlabel)
|
||||
{
|
||||
struct partition *p = lp->d_partitions + dkpart(bp->bio_dev);
|
||||
int labelsect = lp->d_partitions[0].p_offset;
|
||||
int maxsz = p->p_size,
|
||||
sz = (bp->bio_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
|
||||
|
||||
/* overwriting disk label ? */
|
||||
/* XXX should also protect bootstrap in first 8K */
|
||||
if (bp->bio_blkno + p->p_offset <= LABELSECTOR + labelsect &&
|
||||
#if LABELSECTOR != 0
|
||||
bp->bio_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
|
||||
#endif
|
||||
(bp->bio_cmd == BIO_WRITE) && wlabel == 0) {
|
||||
bp->bio_error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
#if defined(DOSBBSECTOR) && defined(notyet)
|
||||
/* overwriting master boot record? */
|
||||
if (bp->bio_blkno + p->p_offset <= DOSBBSECTOR &&
|
||||
(bp->bio_cmd == BIO_WRITE) && wlabel == 0) {
|
||||
bp->bio_error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* beyond partition? */
|
||||
if (bp->bio_blkno < 0 || bp->bio_blkno + sz > maxsz) {
|
||||
/* if exactly at end of disk, return an EOF */
|
||||
if (bp->bio_blkno == maxsz) {
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
return(0);
|
||||
}
|
||||
/* or truncate if part of it fits */
|
||||
sz = maxsz - bp->bio_blkno;
|
||||
if (sz <= 0) {
|
||||
bp->bio_error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
bp->bio_bcount = sz << DEV_BSHIFT;
|
||||
}
|
||||
|
||||
bp->bio_pblkno = bp->bio_blkno + p->p_offset;
|
||||
return(1);
|
||||
|
||||
bad:
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#ifdef __alpha__
|
||||
void
|
||||
alpha_fix_srm_checksum(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
u_int64_t *p;
|
||||
u_int64_t sum;
|
||||
int i;
|
||||
|
||||
p = (u_int64_t *) bp->b_data;
|
||||
sum = 0;
|
||||
for (i = 0; i < 63; i++)
|
||||
sum += p[i];
|
||||
p[63] = sum;
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -1,529 +0,0 @@
|
||||
#ifdef NO_GEOM
|
||||
/*-
|
||||
* Copyright (c) 1994 Bruce D. Evans.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
|
||||
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#ifdef PC98
|
||||
#define PC98_ATCOMPAT
|
||||
#define dsinit atcompat_dsinit
|
||||
#endif
|
||||
#include <sys/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskmbr.h>
|
||||
#define DOSPTYP_EXTENDED 5
|
||||
#define DOSPTYP_EXTENDEDX 15
|
||||
#define DOSPTYP_ONTRACK 84
|
||||
#include <sys/diskslice.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#define TRACE(str) do { if (dsi_debug) printf str; } while (0)
|
||||
|
||||
static volatile u_char dsi_debug;
|
||||
|
||||
/*
|
||||
* This is what we have embedded in every boot1 for supporting the bogus
|
||||
* "Dangerously Dedicated" mode. However, the old table is broken because
|
||||
* it has an illegal geometry in it - it specifies 256 heads (heads = end
|
||||
* head + 1) which causes nasty stuff when that wraps to zero in bios code.
|
||||
* eg: divide by zero etc. This caused the dead-thinkpad problem, numerous
|
||||
* SCSI bios crashes, EFI to crash, etc.
|
||||
*
|
||||
* We still have to recognize the old table though, even though we stopped
|
||||
* inflicting it apon the world.
|
||||
*/
|
||||
static struct dos_partition historical_bogus_partition_table[NDOSPART] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
{ 0x80, 0, 1, 0, DOSPTYP_386BSD, 255, 255, 255, 0, 50000, },
|
||||
};
|
||||
static struct dos_partition historical_bogus_partition_table_fixed[NDOSPART] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
{ 0x80, 0, 1, 0, DOSPTYP_386BSD, 254, 255, 255, 0, 50000, },
|
||||
};
|
||||
|
||||
static int check_part(char *sname, struct dos_partition *dp,
|
||||
u_long offset, int nsectors, int ntracks,
|
||||
u_long mbr_offset);
|
||||
static void mbr_extended(dev_t dev, struct disklabel *lp,
|
||||
struct diskslices *ssp, u_long ext_offset,
|
||||
u_long ext_size, u_long base_ext_offset,
|
||||
int nsectors, int ntracks, u_long mbr_offset,
|
||||
int level);
|
||||
static int mbr_setslice(char *sname, struct disklabel *lp,
|
||||
struct diskslice *sp, struct dos_partition *dp,
|
||||
u_long br_offset);
|
||||
|
||||
static int
|
||||
check_part(sname, dp, offset, nsectors, ntracks, mbr_offset )
|
||||
char *sname;
|
||||
struct dos_partition *dp;
|
||||
u_long offset;
|
||||
int nsectors;
|
||||
int ntracks;
|
||||
u_long mbr_offset;
|
||||
{
|
||||
int chs_ecyl;
|
||||
int chs_esect;
|
||||
int chs_scyl;
|
||||
int chs_ssect;
|
||||
int error;
|
||||
u_long esector;
|
||||
u_long esector1;
|
||||
u_long secpercyl;
|
||||
u_long ssector;
|
||||
u_long ssector1;
|
||||
|
||||
secpercyl = (u_long)nsectors * ntracks;
|
||||
chs_scyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
|
||||
chs_ssect = DPSECT(dp->dp_ssect);
|
||||
ssector = chs_ssect - 1 + dp->dp_shd * nsectors + chs_scyl * secpercyl
|
||||
+ mbr_offset;
|
||||
ssector1 = offset + dp->dp_start;
|
||||
|
||||
/*
|
||||
* If ssector1 is on a cylinder >= 1024, then ssector can't be right.
|
||||
* Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct
|
||||
* apart from the cylinder being reduced modulo 1024. Always allow
|
||||
* 1023/255/63, because this is the official way to represent
|
||||
* pure-LBA for the starting position.
|
||||
*/
|
||||
if ((ssector < ssector1
|
||||
&& ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1
|
||||
&& chs_scyl == 1023)
|
||||
|| (secpercyl != 0
|
||||
&& (ssector1 - ssector) % (1024 * secpercyl) == 0)))
|
||||
|| (dp->dp_scyl == 255 && dp->dp_shd == 255
|
||||
&& dp->dp_ssect == 255)) {
|
||||
TRACE(("%s: C/H/S start %d/%d/%d, start %lu: allow\n",
|
||||
sname, chs_scyl, dp->dp_shd, chs_ssect, ssector1));
|
||||
ssector = ssector1;
|
||||
}
|
||||
|
||||
chs_ecyl = DPCYL(dp->dp_ecyl, dp->dp_esect);
|
||||
chs_esect = DPSECT(dp->dp_esect);
|
||||
esector = chs_esect - 1 + dp->dp_ehd * nsectors + chs_ecyl * secpercyl
|
||||
+ mbr_offset;
|
||||
esector1 = ssector1 + dp->dp_size - 1;
|
||||
|
||||
/*
|
||||
* Allow certain bogus C/H/S values for esector, as above. However,
|
||||
* heads == 255 isn't really legal and causes some BIOS crashes. The
|
||||
* correct value to indicate a pure-LBA end is 1023/heads-1/sectors -
|
||||
* usually 1023/254/63. "heads" is base 0, "sectors" is base 1.
|
||||
*/
|
||||
if ((esector < esector1
|
||||
&& ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1
|
||||
&& chs_ecyl == 1023)
|
||||
|| (secpercyl != 0
|
||||
&& (esector1 - esector) % (1024 * secpercyl) == 0)))
|
||||
|| (dp->dp_ecyl == 255 && dp->dp_ehd == 255
|
||||
&& dp->dp_esect == 255)) {
|
||||
TRACE(("%s: C/H/S end %d/%d/%d, end %lu: allow\n",
|
||||
sname, chs_ecyl, dp->dp_ehd, chs_esect, esector1));
|
||||
esector = esector1;
|
||||
}
|
||||
|
||||
error = (ssector == ssector1 && esector == esector1) ? 0 : EINVAL;
|
||||
if (bootverbose)
|
||||
printf("%s: type 0x%x, start %lu, end = %lu, size %lu %s\n",
|
||||
sname, dp->dp_typ, ssector1, esector1,
|
||||
(u_long)dp->dp_size, error ? "" : ": OK");
|
||||
if (ssector != ssector1 && bootverbose)
|
||||
printf("%s: C/H/S start %d/%d/%d (%lu) != start %lu: invalid\n",
|
||||
sname, chs_scyl, dp->dp_shd, chs_ssect,
|
||||
ssector, ssector1);
|
||||
if (esector != esector1 && bootverbose)
|
||||
printf("%s: C/H/S end %d/%d/%d (%lu) != end %lu: invalid\n",
|
||||
sname, chs_ecyl, dp->dp_ehd, chs_esect,
|
||||
esector, esector1);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
dsinit(dev, lp, sspp)
|
||||
dev_t dev;
|
||||
struct disklabel *lp;
|
||||
struct diskslices **sspp;
|
||||
{
|
||||
struct buf *bp;
|
||||
u_char *cp;
|
||||
int dospart;
|
||||
struct dos_partition *dp;
|
||||
struct dos_partition *dp0;
|
||||
struct dos_partition dpcopy[NDOSPART];
|
||||
int error;
|
||||
int max_ncyls;
|
||||
int max_nsectors;
|
||||
int max_ntracks;
|
||||
u_long mbr_offset;
|
||||
char partname[2];
|
||||
u_long secpercyl;
|
||||
char *sname;
|
||||
struct diskslice *sp;
|
||||
struct diskslices *ssp;
|
||||
|
||||
mbr_offset = DOSBBSECTOR;
|
||||
reread_mbr:
|
||||
/* Read master boot record. */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
|
||||
bp->b_blkno = mbr_offset;
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_iocmd = BIO_READ;
|
||||
DEV_STRATEGY(bp);
|
||||
if (bufwait(bp) != 0) {
|
||||
disk_err(&bp->b_io, "reading primary partition table: error",
|
||||
0, 1);
|
||||
error = EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Weakly verify it. */
|
||||
cp = bp->b_data;
|
||||
sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART, partname);
|
||||
if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
|
||||
if (bootverbose)
|
||||
printf("%s: invalid primary partition table: no magic\n",
|
||||
sname);
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Make a copy of the partition table to avoid alignment problems. */
|
||||
memcpy(&dpcopy[0], cp + DOSPARTOFF, sizeof(dpcopy));
|
||||
|
||||
dp0 = &dpcopy[0];
|
||||
|
||||
/* Check for "Ontrack Diskmanager". */
|
||||
for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
|
||||
if (dp->dp_typ == DOSPTYP_ONTRACK) {
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"%s: Found \"Ontrack Disk Manager\" on this disk.\n", sname);
|
||||
bp->b_flags |= B_INVAL | B_AGE;
|
||||
brelse(bp);
|
||||
mbr_offset = 63;
|
||||
goto reread_mbr;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcmp(dp0, historical_bogus_partition_table,
|
||||
sizeof historical_bogus_partition_table) == 0 ||
|
||||
bcmp(dp0, historical_bogus_partition_table_fixed,
|
||||
sizeof historical_bogus_partition_table_fixed) == 0) {
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"%s: invalid primary partition table: Dangerously Dedicated (ignored)\n",
|
||||
sname);
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Guess the geometry. */
|
||||
/*
|
||||
* TODO:
|
||||
* Perhaps skip entries with 0 size.
|
||||
* Perhaps only look at entries of type DOSPTYP_386BSD.
|
||||
*/
|
||||
max_ncyls = 0;
|
||||
max_nsectors = 0;
|
||||
max_ntracks = 0;
|
||||
for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
|
||||
int ncyls;
|
||||
int nsectors;
|
||||
int ntracks;
|
||||
|
||||
ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect) + 1;
|
||||
if (max_ncyls < ncyls)
|
||||
max_ncyls = ncyls;
|
||||
nsectors = DPSECT(dp->dp_esect);
|
||||
if (max_nsectors < nsectors)
|
||||
max_nsectors = nsectors;
|
||||
ntracks = dp->dp_ehd + 1;
|
||||
if (max_ntracks < ntracks)
|
||||
max_ntracks = ntracks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we have guessed the geometry right by checking the
|
||||
* partition entries.
|
||||
*/
|
||||
/*
|
||||
* TODO:
|
||||
* As above.
|
||||
* Check for overlaps.
|
||||
* Check against d_secperunit if the latter is reliable.
|
||||
*/
|
||||
error = 0;
|
||||
for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
|
||||
if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
|
||||
&& dp->dp_start == 0 && dp->dp_size == 0)
|
||||
continue;
|
||||
sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
|
||||
RAW_PART, partname);
|
||||
|
||||
/*
|
||||
* Temporarily ignore errors from this check. We could
|
||||
* simplify things by accepting the table eariler if we
|
||||
* always ignore errors here. Perhaps we should always
|
||||
* accept the table if the magic is right but not let
|
||||
* bad entries affect the geometry.
|
||||
*/
|
||||
check_part(sname, dp, mbr_offset, max_nsectors, max_ntracks,
|
||||
mbr_offset);
|
||||
}
|
||||
if (error != 0)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Accept the DOS partition table.
|
||||
* First adjust the label (we have been careful not to change it
|
||||
* before we can guarantee success).
|
||||
*/
|
||||
secpercyl = (u_long)max_nsectors * max_ntracks;
|
||||
if (secpercyl != 0) {
|
||||
lp->d_nsectors = max_nsectors;
|
||||
lp->d_ntracks = max_ntracks;
|
||||
lp->d_secpercyl = secpercyl;
|
||||
lp->d_ncylinders = lp->d_secperunit / secpercyl;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are passed a pointer to a suitably initialized minimal
|
||||
* slices "struct" with no dangling pointers in it. Replace it
|
||||
* by a maximal one. This usually oversizes the "struct", but
|
||||
* enlarging it while searching for logical drives would be
|
||||
* inconvenient.
|
||||
*/
|
||||
free(*sspp, M_DEVBUF);
|
||||
ssp = dsmakeslicestruct(MAX_SLICES, lp);
|
||||
*sspp = ssp;
|
||||
|
||||
/* Initialize normal slices. */
|
||||
sp = &ssp->dss_slices[BASE_SLICE];
|
||||
for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++, sp++) {
|
||||
sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
|
||||
RAW_PART, partname);
|
||||
(void)mbr_setslice(sname, lp, sp, dp, mbr_offset);
|
||||
}
|
||||
ssp->dss_nslices = BASE_SLICE + NDOSPART;
|
||||
|
||||
/* Handle extended partitions. */
|
||||
sp -= NDOSPART;
|
||||
for (dospart = 0; dospart < NDOSPART; dospart++, sp++)
|
||||
if (sp->ds_type == DOSPTYP_EXTENDED ||
|
||||
sp->ds_type == DOSPTYP_EXTENDEDX)
|
||||
mbr_extended(bp->b_dev, lp, ssp,
|
||||
sp->ds_offset, sp->ds_size, sp->ds_offset,
|
||||
max_nsectors, max_ntracks, mbr_offset, 1);
|
||||
|
||||
/*
|
||||
* mbr_extended() abuses ssp->dss_nslices for the number of slices
|
||||
* that would be found if there were no limit on the number of slices
|
||||
* in *ssp. Cut it back now.
|
||||
*/
|
||||
if (ssp->dss_nslices > MAX_SLICES)
|
||||
ssp->dss_nslices = MAX_SLICES;
|
||||
|
||||
done:
|
||||
bp->b_flags |= B_INVAL | B_AGE;
|
||||
brelse(bp);
|
||||
if (error == EINVAL)
|
||||
error = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
mbr_extended(dev, lp, ssp, ext_offset, ext_size, base_ext_offset, nsectors,
|
||||
ntracks, mbr_offset, level)
|
||||
dev_t dev;
|
||||
struct disklabel *lp;
|
||||
struct diskslices *ssp;
|
||||
u_long ext_offset;
|
||||
u_long ext_size;
|
||||
u_long base_ext_offset;
|
||||
int nsectors;
|
||||
int ntracks;
|
||||
u_long mbr_offset;
|
||||
int level;
|
||||
{
|
||||
struct buf *bp;
|
||||
u_char *cp;
|
||||
int dospart;
|
||||
struct dos_partition *dp;
|
||||
struct dos_partition dpcopy[NDOSPART];
|
||||
u_long ext_offsets[NDOSPART];
|
||||
u_long ext_sizes[NDOSPART];
|
||||
char partname[2];
|
||||
int slice;
|
||||
char *sname;
|
||||
struct diskslice *sp;
|
||||
|
||||
if (level >= 16) {
|
||||
printf(
|
||||
"%s: excessive recursion in search for slices; aborting search\n",
|
||||
devtoname(dev));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read extended boot record. */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
bp->b_dev = dev;
|
||||
bp->b_blkno = ext_offset;
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_iocmd = BIO_READ;
|
||||
DEV_STRATEGY(bp);
|
||||
if (bufwait(bp) != 0) {
|
||||
disk_err(&bp->b_io, "reading extended partition table: error",
|
||||
0, 1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Weakly verify it. */
|
||||
cp = bp->b_data;
|
||||
if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
|
||||
sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART,
|
||||
partname);
|
||||
if (bootverbose)
|
||||
printf("%s: invalid extended partition table: no magic\n",
|
||||
sname);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Make a copy of the partition table to avoid alignment problems. */
|
||||
memcpy(&dpcopy[0], cp + DOSPARTOFF, sizeof(dpcopy));
|
||||
|
||||
slice = ssp->dss_nslices;
|
||||
for (dospart = 0, dp = &dpcopy[0]; dospart < NDOSPART;
|
||||
dospart++, dp++) {
|
||||
ext_sizes[dospart] = 0;
|
||||
if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
|
||||
&& dp->dp_start == 0 && dp->dp_size == 0)
|
||||
continue;
|
||||
if (dp->dp_typ == DOSPTYP_EXTENDED ||
|
||||
dp->dp_typ == DOSPTYP_EXTENDEDX) {
|
||||
static char buf[32];
|
||||
|
||||
sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE,
|
||||
RAW_PART, partname);
|
||||
snprintf(buf, sizeof(buf), "%s", sname);
|
||||
if (strlen(buf) < sizeof buf - 11)
|
||||
strcat(buf, "<extended>");
|
||||
check_part(buf, dp, base_ext_offset, nsectors,
|
||||
ntracks, mbr_offset);
|
||||
ext_offsets[dospart] = base_ext_offset + dp->dp_start;
|
||||
ext_sizes[dospart] = dp->dp_size;
|
||||
} else {
|
||||
sname = dsname(dev, dkunit(dev), slice, RAW_PART,
|
||||
partname);
|
||||
check_part(sname, dp, ext_offset, nsectors, ntracks,
|
||||
mbr_offset);
|
||||
if (slice >= MAX_SLICES) {
|
||||
printf("%s: too many slices\n", sname);
|
||||
slice++;
|
||||
continue;
|
||||
}
|
||||
sp = &ssp->dss_slices[slice];
|
||||
if (mbr_setslice(sname, lp, sp, dp, ext_offset) != 0)
|
||||
continue;
|
||||
slice++;
|
||||
}
|
||||
}
|
||||
ssp->dss_nslices = slice;
|
||||
|
||||
/* If we found any more slices, recursively find all the subslices. */
|
||||
for (dospart = 0; dospart < NDOSPART; dospart++)
|
||||
if (ext_sizes[dospart] != 0)
|
||||
mbr_extended(dev, lp, ssp, ext_offsets[dospart],
|
||||
ext_sizes[dospart], base_ext_offset,
|
||||
nsectors, ntracks, mbr_offset, ++level);
|
||||
|
||||
done:
|
||||
bp->b_flags |= B_INVAL | B_AGE;
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
static int
|
||||
mbr_setslice(sname, lp, sp, dp, br_offset)
|
||||
char *sname;
|
||||
struct disklabel *lp;
|
||||
struct diskslice *sp;
|
||||
struct dos_partition *dp;
|
||||
u_long br_offset;
|
||||
{
|
||||
u_long offset;
|
||||
u_long size;
|
||||
|
||||
offset = br_offset + dp->dp_start;
|
||||
if (offset > lp->d_secperunit || offset < br_offset) {
|
||||
printf(
|
||||
"%s: slice starts beyond end of the disk: rejecting it\n",
|
||||
sname);
|
||||
return (1);
|
||||
}
|
||||
size = lp->d_secperunit - offset;
|
||||
if (size >= dp->dp_size)
|
||||
size = dp->dp_size;
|
||||
else
|
||||
printf(
|
||||
"%s: slice extends beyond end of disk: truncating from %lu to %lu sectors\n",
|
||||
sname, (u_long)dp->dp_size, size);
|
||||
sp->ds_offset = offset;
|
||||
sp->ds_size = size;
|
||||
sp->ds_type = dp->dp_typ;
|
||||
#ifdef PC98_ATCOMPAT
|
||||
/* Fake FreeBSD(98). */
|
||||
if (sp->ds_type == DOSPTYP_386BSD)
|
||||
sp->ds_type = 0x94;
|
||||
#endif
|
||||
#if 0
|
||||
lp->d_subtype |= (lp->d_subtype & 3) | dospart | DSTYPE_INDOSPART;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
#endif
|
@ -1,940 +0,0 @@
|
||||
#ifdef NO_GEOM
|
||||
/*-
|
||||
* Copyright (c) 1994 Bruce D. Evans.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz.
|
||||
*
|
||||
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
|
||||
* from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $
|
||||
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
|
||||
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskslice.h>
|
||||
#if defined(PC98) && !defined(PC98_ATCOMPAT)
|
||||
#include <sys/diskpc98.h>
|
||||
#else
|
||||
#include <sys/diskmbr.h>
|
||||
#endif
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#define TRACE(str) do { if (ds_debug) printf str; } while (0)
|
||||
|
||||
typedef u_char bool_t;
|
||||
|
||||
static volatile bool_t ds_debug;
|
||||
|
||||
static struct disklabel *clone_label(struct disklabel *lp);
|
||||
static void dsiodone(struct bio *bp);
|
||||
static char *fixlabel(char *sname, struct diskslice *sp,
|
||||
struct disklabel *lp, int writeflag);
|
||||
static void free_ds_label(struct diskslices *ssp, int slice);
|
||||
static void partition_info(char *sname, int part, struct partition *pp);
|
||||
static void slice_info(char *sname, struct diskslice *sp);
|
||||
static void set_ds_label(struct diskslices *ssp, int slice,
|
||||
struct disklabel *lp);
|
||||
static void set_ds_labeldevs(dev_t dev, struct diskslices *ssp);
|
||||
static void set_ds_wlabel(struct diskslices *ssp, int slice,
|
||||
int wlabel);
|
||||
|
||||
/*
|
||||
* Duplicate a label for the whole disk, and initialize defaults in the
|
||||
* copy for fields that are not already initialized. The caller only
|
||||
* needs to initialize d_secsize and d_secperunit, and zero the fields
|
||||
* that are to be defaulted.
|
||||
*/
|
||||
static struct disklabel *
|
||||
clone_label(lp)
|
||||
struct disklabel *lp;
|
||||
{
|
||||
struct disklabel *lp1;
|
||||
|
||||
lp1 = malloc(sizeof *lp1, M_DEVBUF, 0);
|
||||
*lp1 = *lp;
|
||||
lp = NULL;
|
||||
if (lp1->d_typename[0] == '\0')
|
||||
strlcpy(lp1->d_typename, "amnesiac", sizeof(lp1->d_typename));
|
||||
if (lp1->d_packname[0] == '\0')
|
||||
strlcpy(lp1->d_packname, "fictitious", sizeof(lp1->d_packname));
|
||||
if (lp1->d_nsectors == 0)
|
||||
lp1->d_nsectors = 32;
|
||||
if (lp1->d_ntracks == 0)
|
||||
lp1->d_ntracks = 64;
|
||||
lp1->d_secpercyl = lp1->d_nsectors * lp1->d_ntracks;
|
||||
lp1->d_ncylinders = lp1->d_secperunit / lp1->d_secpercyl;
|
||||
if (lp1->d_rpm == 0)
|
||||
lp1->d_rpm = 3600;
|
||||
if (lp1->d_interleave == 0)
|
||||
lp1->d_interleave = 1;
|
||||
if (lp1->d_npartitions < RAW_PART + 1)
|
||||
lp1->d_npartitions = MAXPARTITIONS;
|
||||
if (lp1->d_bbsize == 0)
|
||||
lp1->d_bbsize = BBSIZE;
|
||||
lp1->d_partitions[RAW_PART].p_size = lp1->d_secperunit;
|
||||
lp1->d_magic = DISKMAGIC;
|
||||
lp1->d_magic2 = DISKMAGIC;
|
||||
lp1->d_checksum = dkcksum(lp1);
|
||||
return (lp1);
|
||||
}
|
||||
|
||||
dev_t
|
||||
dkmodslice(dev_t dev, int slice)
|
||||
{
|
||||
return (makedev(major(dev), (minor(dev) & ~0x1f0000) | (slice << 16)));
|
||||
}
|
||||
|
||||
u_int
|
||||
dkunit(dev_t dev)
|
||||
{
|
||||
return (((minor(dev) >> 16) & 0x1e0) | ((minor(dev) >> 3) & 0x1f));
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the size of the transfer, and make sure it is
|
||||
* within the boundaries of the partition. Adjust transfer
|
||||
* if needed, and signal errors or early completion.
|
||||
*
|
||||
* XXX TODO:
|
||||
* o Split buffers that are too big for the device.
|
||||
* o Check for overflow.
|
||||
* o Finish cleaning this up.
|
||||
*/
|
||||
int
|
||||
dscheck(bp, ssp)
|
||||
struct bio *bp;
|
||||
struct diskslices *ssp;
|
||||
{
|
||||
daddr_t blkno;
|
||||
daddr_t endsecno;
|
||||
daddr_t labelsect;
|
||||
struct disklabel *lp;
|
||||
char *msg;
|
||||
long nsec;
|
||||
struct partition *pp;
|
||||
daddr_t secno;
|
||||
daddr_t slicerel_secno;
|
||||
struct diskslice *sp;
|
||||
|
||||
blkno = bp->bio_blkno;
|
||||
if (blkno < 0) {
|
||||
printf("dscheck(%s): negative bio_blkno %ld\n",
|
||||
devtoname(bp->bio_dev), (long)blkno);
|
||||
bp->bio_error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
sp = &ssp->dss_slices[dkslice(bp->bio_dev)];
|
||||
lp = sp->ds_label;
|
||||
if (ssp->dss_secmult == 1) {
|
||||
if (bp->bio_bcount % (u_long)DEV_BSIZE)
|
||||
goto bad_bcount;
|
||||
secno = blkno;
|
||||
nsec = bp->bio_bcount >> DEV_BSHIFT;
|
||||
} else if (ssp->dss_secshift != -1) {
|
||||
if (bp->bio_bcount & (ssp->dss_secsize - 1))
|
||||
goto bad_bcount;
|
||||
if (blkno & (ssp->dss_secmult - 1))
|
||||
goto bad_blkno;
|
||||
secno = blkno >> ssp->dss_secshift;
|
||||
nsec = bp->bio_bcount >> (DEV_BSHIFT + ssp->dss_secshift);
|
||||
} else {
|
||||
if (bp->bio_bcount % ssp->dss_secsize)
|
||||
goto bad_bcount;
|
||||
if (blkno % ssp->dss_secmult)
|
||||
goto bad_blkno;
|
||||
secno = blkno / ssp->dss_secmult;
|
||||
nsec = bp->bio_bcount / ssp->dss_secsize;
|
||||
}
|
||||
if (lp == NULL) {
|
||||
labelsect = -LABELSECTOR - 1;
|
||||
endsecno = sp->ds_size;
|
||||
slicerel_secno = secno;
|
||||
} else {
|
||||
labelsect = lp->d_partitions[LABEL_PART].p_offset;
|
||||
if (labelsect != 0)
|
||||
Debugger("labelsect != 0 in dscheck()");
|
||||
pp = &lp->d_partitions[dkpart(bp->bio_dev)];
|
||||
endsecno = pp->p_size;
|
||||
slicerel_secno = pp->p_offset + secno;
|
||||
}
|
||||
|
||||
/* overwriting disk label ? */
|
||||
/* XXX should also protect bootstrap in first 8K */
|
||||
if (slicerel_secno <= LABELSECTOR + labelsect &&
|
||||
#if LABELSECTOR != 0
|
||||
slicerel_secno + nsec > LABELSECTOR + labelsect &&
|
||||
#endif
|
||||
(bp->bio_cmd == BIO_WRITE) && sp->ds_wlabel == 0) {
|
||||
bp->bio_error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
#if defined(DOSBBSECTOR) && defined(notyet)
|
||||
/* overwriting master boot record? */
|
||||
if (slicerel_secno <= DOSBBSECTOR && (bp->bio_cmd == BIO_WRITE) &&
|
||||
sp->ds_wlabel == 0) {
|
||||
bp->bio_error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* beyond partition? */
|
||||
if ((uintmax_t)secno + nsec > endsecno) {
|
||||
/* if exactly at end of disk, return an EOF */
|
||||
if (secno == endsecno) {
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
return (0);
|
||||
}
|
||||
/* or truncate if part of it fits */
|
||||
if (secno > endsecno) {
|
||||
bp->bio_error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
bp->bio_bcount = (endsecno - secno) * ssp->dss_secsize;
|
||||
}
|
||||
|
||||
bp->bio_pblkno = sp->ds_offset + slicerel_secno;
|
||||
|
||||
/*
|
||||
* Snoop on label accesses if the slice offset is nonzero. Fudge
|
||||
* offsets in the label to keep the in-core label coherent with
|
||||
* the on-disk one.
|
||||
*/
|
||||
if (slicerel_secno <= LABELSECTOR + labelsect
|
||||
#if LABELSECTOR != 0
|
||||
&& slicerel_secno + nsec > LABELSECTOR + labelsect
|
||||
#endif
|
||||
&& sp->ds_offset != 0) {
|
||||
struct iodone_chain *ic;
|
||||
|
||||
ic = malloc(sizeof *ic , M_DEVBUF, 0);
|
||||
ic->ic_prev_flags = bp->bio_flags;
|
||||
ic->ic_prev_iodone = bp->bio_done;
|
||||
ic->ic_prev_iodone_chain = bp->bio_done_chain;
|
||||
ic->ic_args[0].ia_long = (LABELSECTOR + labelsect -
|
||||
slicerel_secno) * ssp->dss_secsize;
|
||||
ic->ic_args[1].ia_ptr = sp;
|
||||
bp->bio_done = dsiodone;
|
||||
bp->bio_done_chain = ic;
|
||||
if (!(bp->bio_cmd == BIO_READ)) {
|
||||
/*
|
||||
* XXX even disklabel(8) writes directly so we need
|
||||
* to adjust writes. Perhaps we should drop support
|
||||
* for DIOCWLABEL (always write protect labels) and
|
||||
* require the use of DIOCWDINFO.
|
||||
*
|
||||
* XXX probably need to copy the data to avoid even
|
||||
* temporarily corrupting the in-core copy.
|
||||
*/
|
||||
/* XXX need name here. */
|
||||
msg = fixlabel((char *)NULL, sp,
|
||||
(struct disklabel *)
|
||||
(bp->bio_data + ic->ic_args[0].ia_long),
|
||||
TRUE);
|
||||
if (msg != NULL) {
|
||||
printf("dscheck(%s): %s\n",
|
||||
devtoname(bp->bio_dev), msg);
|
||||
bp->bio_error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
|
||||
bad_bcount:
|
||||
printf(
|
||||
"dscheck(%s): bio_bcount %ld is not on a sector boundary (ssize %d)\n",
|
||||
devtoname(bp->bio_dev), bp->bio_bcount, ssp->dss_secsize);
|
||||
bp->bio_error = EINVAL;
|
||||
goto bad;
|
||||
|
||||
bad_blkno:
|
||||
printf(
|
||||
"dscheck(%s): bio_blkno %ld is not on a sector boundary (ssize %d)\n",
|
||||
devtoname(bp->bio_dev), (long)blkno, ssp->dss_secsize);
|
||||
bp->bio_error = EINVAL;
|
||||
goto bad;
|
||||
|
||||
bad:
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
dsclose(dev, mode, ssp)
|
||||
dev_t dev;
|
||||
int mode;
|
||||
struct diskslices *ssp;
|
||||
{
|
||||
u_char mask;
|
||||
struct diskslice *sp;
|
||||
|
||||
sp = &ssp->dss_slices[dkslice(dev)];
|
||||
mask = 1 << dkpart(dev);
|
||||
sp->ds_openmask &= ~mask;
|
||||
}
|
||||
|
||||
void
|
||||
dsgone(sspp)
|
||||
struct diskslices **sspp;
|
||||
{
|
||||
int slice;
|
||||
struct diskslice *sp;
|
||||
struct diskslices *ssp;
|
||||
|
||||
for (slice = 0, ssp = *sspp; slice < ssp->dss_nslices; slice++) {
|
||||
sp = &ssp->dss_slices[slice];
|
||||
free_ds_label(ssp, slice);
|
||||
}
|
||||
free(ssp, M_DEVBUF);
|
||||
*sspp = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the "write" commands (DIOCSDINFO and DIOCWDINFO), this
|
||||
* is subject to the same restriction as dsopen().
|
||||
*/
|
||||
int
|
||||
dsioctl(dev, cmd, data, flags, sspp)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flags;
|
||||
struct diskslices **sspp;
|
||||
{
|
||||
int error;
|
||||
struct disklabel *lp;
|
||||
int old_wlabel;
|
||||
u_char openmask;
|
||||
int part;
|
||||
int slice;
|
||||
struct diskslice *sp;
|
||||
struct diskslices *ssp;
|
||||
|
||||
slice = dkslice(dev);
|
||||
ssp = *sspp;
|
||||
sp = &ssp->dss_slices[slice];
|
||||
lp = sp->ds_label;
|
||||
switch (cmd) {
|
||||
|
||||
case DIOCGDINFO:
|
||||
if (lp == NULL)
|
||||
return (EINVAL);
|
||||
*(struct disklabel *)data = *lp;
|
||||
return (0);
|
||||
|
||||
case DIOCGMEDIASIZE:
|
||||
if (lp == NULL)
|
||||
*(off_t *)data = (off_t)sp->ds_size * ssp->dss_secsize;
|
||||
else
|
||||
*(off_t *)data =
|
||||
(off_t)lp->d_partitions[dkpart(dev)].p_size *
|
||||
lp->d_secsize;
|
||||
return (0);
|
||||
|
||||
case DIOCGSECTORSIZE:
|
||||
*(u_int *)data = ssp->dss_secsize;
|
||||
return (0);
|
||||
|
||||
case DIOCGSLICEINFO:
|
||||
bcopy(ssp, data, (char *)&ssp->dss_slices[ssp->dss_nslices] -
|
||||
(char *)ssp);
|
||||
return (0);
|
||||
|
||||
case DIOCSDINFO:
|
||||
if (slice == WHOLE_DISK_SLICE)
|
||||
return (ENODEV);
|
||||
if (!(flags & FWRITE))
|
||||
return (EBADF);
|
||||
lp = malloc(sizeof *lp, M_DEVBUF, 0);
|
||||
if (sp->ds_label == NULL)
|
||||
bzero(lp, sizeof *lp);
|
||||
else
|
||||
bcopy(sp->ds_label, lp, sizeof *lp);
|
||||
if (sp->ds_label == NULL)
|
||||
openmask = 0;
|
||||
else {
|
||||
openmask = sp->ds_openmask;
|
||||
if (slice == COMPATIBILITY_SLICE)
|
||||
openmask |= ssp->dss_slices[
|
||||
ssp->dss_first_bsd_slice].ds_openmask;
|
||||
else if (slice == ssp->dss_first_bsd_slice)
|
||||
openmask |= ssp->dss_slices[
|
||||
COMPATIBILITY_SLICE].ds_openmask;
|
||||
}
|
||||
error = setdisklabel(lp, (struct disklabel *)data,
|
||||
(u_long)openmask);
|
||||
/* XXX why doesn't setdisklabel() check this? */
|
||||
if (error == 0 && lp->d_partitions[RAW_PART].p_offset != 0)
|
||||
error = EXDEV;
|
||||
if (error == 0) {
|
||||
if (lp->d_secperunit > sp->ds_size)
|
||||
error = ENOSPC;
|
||||
for (part = 0; part < lp->d_npartitions; part++)
|
||||
if (lp->d_partitions[part].p_size > sp->ds_size)
|
||||
error = ENOSPC;
|
||||
}
|
||||
if (error != 0) {
|
||||
free(lp, M_DEVBUF);
|
||||
return (error);
|
||||
}
|
||||
free_ds_label(ssp, slice);
|
||||
set_ds_label(ssp, slice, lp);
|
||||
set_ds_labeldevs(dev, ssp);
|
||||
return (0);
|
||||
|
||||
case DIOCSYNCSLICEINFO:
|
||||
if (slice != WHOLE_DISK_SLICE || dkpart(dev) != RAW_PART)
|
||||
return (EINVAL);
|
||||
if (!*(int *)data)
|
||||
for (slice = 0; slice < ssp->dss_nslices; slice++) {
|
||||
openmask = ssp->dss_slices[slice].ds_openmask;
|
||||
if (openmask
|
||||
&& (slice != WHOLE_DISK_SLICE
|
||||
|| openmask & ~(1 << RAW_PART)))
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporarily forget the current slices struct and read
|
||||
* the current one.
|
||||
* XXX should wait for current accesses on this disk to
|
||||
* complete, then lock out future accesses and opens.
|
||||
*/
|
||||
*sspp = NULL;
|
||||
lp = malloc(sizeof *lp, M_DEVBUF, 0);
|
||||
*lp = *ssp->dss_slices[WHOLE_DISK_SLICE].ds_label;
|
||||
error = dsopen(dev, S_IFCHR, ssp->dss_oflags, sspp, lp);
|
||||
if (error != 0) {
|
||||
free(lp, M_DEVBUF);
|
||||
*sspp = ssp;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reopen everything. This is a no-op except in the "force"
|
||||
* case and when the raw bdev and cdev are both open. Abort
|
||||
* if anything fails.
|
||||
*/
|
||||
for (slice = 0; slice < ssp->dss_nslices; slice++) {
|
||||
for (openmask = ssp->dss_slices[slice].ds_openmask,
|
||||
part = 0; openmask; openmask >>= 1, part++) {
|
||||
if (!(openmask & 1))
|
||||
continue;
|
||||
error = dsopen(dkmodslice(dkmodpart(dev, part),
|
||||
slice),
|
||||
S_IFCHR, ssp->dss_oflags, sspp,
|
||||
lp);
|
||||
if (error != 0) {
|
||||
free(lp, M_DEVBUF);
|
||||
*sspp = ssp;
|
||||
return (EBUSY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(lp, M_DEVBUF);
|
||||
dsgone(&ssp);
|
||||
return (0);
|
||||
|
||||
case DIOCWDINFO:
|
||||
error = dsioctl(dev, DIOCSDINFO, data, flags, &ssp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
/*
|
||||
* XXX this used to hack on dk_openpart to fake opening
|
||||
* partition 0 in case that is used instead of dkpart(dev).
|
||||
*/
|
||||
old_wlabel = sp->ds_wlabel;
|
||||
set_ds_wlabel(ssp, slice, TRUE);
|
||||
error = writedisklabel(dev, sp->ds_label);
|
||||
/* XXX should invalidate in-core label if write failed. */
|
||||
set_ds_wlabel(ssp, slice, old_wlabel);
|
||||
return (error);
|
||||
|
||||
case DIOCWLABEL:
|
||||
#ifndef __alpha__
|
||||
if (slice == WHOLE_DISK_SLICE)
|
||||
return (ENODEV);
|
||||
#endif
|
||||
if (!(flags & FWRITE))
|
||||
return (EBADF);
|
||||
set_ds_wlabel(ssp, slice, *(int *)data != 0);
|
||||
return (0);
|
||||
|
||||
default:
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dsiodone(bp)
|
||||
struct bio *bp;
|
||||
{
|
||||
struct iodone_chain *ic;
|
||||
char *msg;
|
||||
|
||||
ic = bp->bio_done_chain;
|
||||
bp->bio_done = ic->ic_prev_iodone;
|
||||
bp->bio_done_chain = ic->ic_prev_iodone_chain;
|
||||
if (!(bp->bio_cmd == BIO_READ)
|
||||
|| (!(bp->bio_flags & BIO_ERROR) && bp->bio_error == 0)) {
|
||||
msg = fixlabel((char *)NULL, ic->ic_args[1].ia_ptr,
|
||||
(struct disklabel *)
|
||||
(bp->bio_data + ic->ic_args[0].ia_long),
|
||||
FALSE);
|
||||
if (msg != NULL)
|
||||
printf("%s\n", msg);
|
||||
}
|
||||
free(ic, M_DEVBUF);
|
||||
biodone(bp);
|
||||
}
|
||||
|
||||
int
|
||||
dsisopen(ssp)
|
||||
struct diskslices *ssp;
|
||||
{
|
||||
int slice;
|
||||
|
||||
if (ssp == NULL)
|
||||
return (0);
|
||||
for (slice = 0; slice < ssp->dss_nslices; slice++)
|
||||
if (ssp->dss_slices[slice].ds_openmask)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a slices "struct" and initialize it to contain only an empty
|
||||
* compatibility slice (pointing to itself), a whole disk slice (covering
|
||||
* the disk as described by the label), and (nslices - BASE_SLICES) empty
|
||||
* slices beginning at BASE_SLICE.
|
||||
*/
|
||||
struct diskslices *
|
||||
dsmakeslicestruct(nslices, lp)
|
||||
int nslices;
|
||||
struct disklabel *lp;
|
||||
{
|
||||
struct diskslice *sp;
|
||||
struct diskslices *ssp;
|
||||
|
||||
ssp = malloc(offsetof(struct diskslices, dss_slices) +
|
||||
nslices * sizeof *sp, M_DEVBUF, 0);
|
||||
ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
|
||||
ssp->dss_nslices = nslices;
|
||||
ssp->dss_oflags = 0;
|
||||
ssp->dss_secmult = lp->d_secsize / DEV_BSIZE;
|
||||
if (ssp->dss_secmult & (ssp->dss_secmult - 1))
|
||||
ssp->dss_secshift = -1;
|
||||
else
|
||||
ssp->dss_secshift = ffs(ssp->dss_secmult) - 1;
|
||||
ssp->dss_secsize = lp->d_secsize;
|
||||
sp = &ssp->dss_slices[0];
|
||||
bzero(sp, nslices * sizeof *sp);
|
||||
sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
|
||||
return (ssp);
|
||||
}
|
||||
|
||||
char *
|
||||
dsname(dev, unit, slice, part, partname)
|
||||
dev_t dev;
|
||||
int unit;
|
||||
int slice;
|
||||
int part;
|
||||
char *partname;
|
||||
{
|
||||
static char name[32];
|
||||
const char *dname;
|
||||
|
||||
dname = devsw(dev)->d_name;
|
||||
if (strlen(dname) > 16)
|
||||
dname = "nametoolong";
|
||||
snprintf(name, sizeof(name), "%s%d", dname, unit);
|
||||
partname[0] = '\0';
|
||||
if (slice != WHOLE_DISK_SLICE || part != RAW_PART) {
|
||||
partname[0] = 'a' + part;
|
||||
partname[1] = '\0';
|
||||
if (slice != COMPATIBILITY_SLICE)
|
||||
snprintf(name + strlen(name),
|
||||
sizeof(name) - strlen(name), "s%d", slice - 1);
|
||||
}
|
||||
return (name);
|
||||
}
|
||||
|
||||
/*
|
||||
* This should only be called when the unit is inactive and the strategy
|
||||
* routine should not allow it to become active unless we call it. Our
|
||||
* strategy routine must be special to allow activity.
|
||||
*/
|
||||
int
|
||||
dsopen(dev, mode, flags, sspp, lp)
|
||||
dev_t dev;
|
||||
int mode;
|
||||
u_int flags;
|
||||
struct diskslices **sspp;
|
||||
struct disklabel *lp;
|
||||
{
|
||||
dev_t dev1;
|
||||
int error;
|
||||
struct disklabel *lp1;
|
||||
char *msg;
|
||||
u_char mask;
|
||||
int part;
|
||||
char partname[2];
|
||||
int slice;
|
||||
char *sname;
|
||||
struct diskslice *sp;
|
||||
struct diskslices *ssp;
|
||||
int unit;
|
||||
|
||||
dev->si_bsize_phys = lp->d_secsize;
|
||||
|
||||
unit = dkunit(dev);
|
||||
if (lp->d_secsize % DEV_BSIZE) {
|
||||
printf("%s: invalid sector size %lu\n", devtoname(dev),
|
||||
(u_long)lp->d_secsize);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX reinitialize the slice table unless there is an open device
|
||||
* on the unit. This should only be done if the media has changed.
|
||||
*/
|
||||
ssp = *sspp;
|
||||
if (!dsisopen(ssp)) {
|
||||
if (ssp != NULL)
|
||||
dsgone(sspp);
|
||||
/*
|
||||
* Allocate a minimal slices "struct". This will become
|
||||
* the final slices "struct" if we don't want real slices
|
||||
* or if we can't find any real slices.
|
||||
*/
|
||||
*sspp = dsmakeslicestruct(BASE_SLICE, lp);
|
||||
|
||||
TRACE(("dsinit\n"));
|
||||
error = dsinit(dev, lp, sspp);
|
||||
if (error != 0) {
|
||||
dsgone(sspp);
|
||||
return (error);
|
||||
}
|
||||
ssp = *sspp;
|
||||
ssp->dss_oflags = flags;
|
||||
|
||||
/*
|
||||
* If there are no real slices, then make the compatiblity
|
||||
* slice cover the whole disk.
|
||||
*/
|
||||
if (ssp->dss_nslices == BASE_SLICE)
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_size
|
||||
= lp->d_secperunit;
|
||||
|
||||
/* Point the compatibility slice at the BSD slice, if any. */
|
||||
for (slice = BASE_SLICE; slice < ssp->dss_nslices; slice++) {
|
||||
sp = &ssp->dss_slices[slice];
|
||||
if (sp->ds_type == DOSPTYP_386BSD /* XXX */) {
|
||||
ssp->dss_first_bsd_slice = slice;
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_offset
|
||||
= sp->ds_offset;
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_size
|
||||
= sp->ds_size;
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_type
|
||||
= sp->ds_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ssp->dss_slices[WHOLE_DISK_SLICE].ds_label = clone_label(lp);
|
||||
ssp->dss_slices[WHOLE_DISK_SLICE].ds_wlabel = TRUE;
|
||||
}
|
||||
|
||||
/* Initialize secondary info for all slices. */
|
||||
for (slice = 0; slice < ssp->dss_nslices; slice++) {
|
||||
sp = &ssp->dss_slices[slice];
|
||||
if (sp->ds_label != NULL
|
||||
#ifdef __alpha__
|
||||
&& slice != WHOLE_DISK_SLICE
|
||||
#endif
|
||||
)
|
||||
continue;
|
||||
dev1 = dkmodslice(dkmodpart(dev, RAW_PART), slice);
|
||||
#if 0
|
||||
sname = dsname(dev, unit, slice, RAW_PART, partname);
|
||||
#else
|
||||
*partname='\0';
|
||||
sname = dev1->si_name;
|
||||
#endif
|
||||
/*
|
||||
* XXX this should probably only be done for the need_init
|
||||
* case, but there may be a problem with DIOCSYNCSLICEINFO.
|
||||
*/
|
||||
set_ds_wlabel(ssp, slice, TRUE); /* XXX invert */
|
||||
lp1 = clone_label(lp);
|
||||
TRACE(("readdisklabel\n"));
|
||||
msg = readdisklabel(dev1, lp1);
|
||||
if (msg == NULL)
|
||||
msg = fixlabel(sname, sp, lp1, FALSE);
|
||||
if (msg == NULL && lp1->d_secsize != ssp->dss_secsize)
|
||||
msg = "inconsistent sector size";
|
||||
if (msg != NULL) {
|
||||
if (sp->ds_type == DOSPTYP_386BSD /* XXX */)
|
||||
log(LOG_WARNING, "%s: cannot find label (%s)\n",
|
||||
sname, msg);
|
||||
free(lp1, M_DEVBUF);
|
||||
continue;
|
||||
}
|
||||
if (lp1->d_flags & D_BADSECT) {
|
||||
log(LOG_ERR, "%s: bad sector table not supported\n",
|
||||
sname);
|
||||
free(lp1, M_DEVBUF);
|
||||
continue;
|
||||
}
|
||||
set_ds_label(ssp, slice, lp1);
|
||||
set_ds_labeldevs(dev1, ssp);
|
||||
set_ds_wlabel(ssp, slice, FALSE);
|
||||
}
|
||||
|
||||
slice = dkslice(dev);
|
||||
if (slice >= ssp->dss_nslices)
|
||||
return (ENXIO);
|
||||
sp = &ssp->dss_slices[slice];
|
||||
part = dkpart(dev);
|
||||
if (part != RAW_PART
|
||||
&& (sp->ds_label == NULL || part >= sp->ds_label->d_npartitions))
|
||||
return (EINVAL); /* XXX needs translation */
|
||||
mask = 1 << part;
|
||||
sp->ds_openmask |= mask;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
dssize(dev, sspp)
|
||||
dev_t dev;
|
||||
struct diskslices **sspp;
|
||||
{
|
||||
struct disklabel *lp;
|
||||
int part;
|
||||
int slice;
|
||||
struct diskslices *ssp;
|
||||
|
||||
slice = dkslice(dev);
|
||||
part = dkpart(dev);
|
||||
ssp = *sspp;
|
||||
if (ssp == NULL || slice >= ssp->dss_nslices
|
||||
|| !(ssp->dss_slices[slice].ds_openmask & (1 << part))) {
|
||||
if (devsw(dev)->d_open(dev, FREAD, S_IFCHR,
|
||||
(struct thread *)NULL) != 0)
|
||||
return (-1);
|
||||
devsw(dev)->d_close(dev, FREAD, S_IFCHR, (struct thread *)NULL);
|
||||
ssp = *sspp;
|
||||
}
|
||||
lp = ssp->dss_slices[slice].ds_label;
|
||||
if (lp == NULL)
|
||||
return (-1);
|
||||
return ((int)lp->d_partitions[part].p_size);
|
||||
}
|
||||
|
||||
static void
|
||||
free_ds_label(ssp, slice)
|
||||
struct diskslices *ssp;
|
||||
int slice;
|
||||
{
|
||||
struct disklabel *lp;
|
||||
struct diskslice *sp;
|
||||
|
||||
sp = &ssp->dss_slices[slice];
|
||||
lp = sp->ds_label;
|
||||
if (lp == NULL)
|
||||
return;
|
||||
free(lp, M_DEVBUF);
|
||||
set_ds_label(ssp, slice, (struct disklabel *)NULL);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
fixlabel(sname, sp, lp, writeflag)
|
||||
char *sname;
|
||||
struct diskslice *sp;
|
||||
struct disklabel *lp;
|
||||
int writeflag;
|
||||
{
|
||||
u_long end;
|
||||
u_long offset;
|
||||
int part;
|
||||
struct partition *pp;
|
||||
u_long start;
|
||||
bool_t warned;
|
||||
|
||||
/* These errors "can't happen" so don't bother reporting details. */
|
||||
if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC)
|
||||
return ("fixlabel: invalid magic");
|
||||
if (dkcksum(lp) != 0)
|
||||
return ("fixlabel: invalid checksum");
|
||||
|
||||
pp = &lp->d_partitions[RAW_PART];
|
||||
if (writeflag) {
|
||||
start = 0;
|
||||
offset = sp->ds_offset;
|
||||
} else {
|
||||
start = sp->ds_offset;
|
||||
offset = -sp->ds_offset;
|
||||
}
|
||||
if (pp->p_offset != start) {
|
||||
if (sname != NULL) {
|
||||
printf(
|
||||
"%s: rejecting BSD label: raw partition offset != slice offset\n",
|
||||
sname);
|
||||
slice_info(sname, sp);
|
||||
partition_info(sname, RAW_PART, pp);
|
||||
}
|
||||
return ("fixlabel: raw partition offset != slice offset");
|
||||
}
|
||||
if (pp->p_size != sp->ds_size) {
|
||||
if (sname != NULL) {
|
||||
printf("%s: raw partition size != slice size\n", sname);
|
||||
slice_info(sname, sp);
|
||||
partition_info(sname, RAW_PART, pp);
|
||||
}
|
||||
if (pp->p_size > sp->ds_size) {
|
||||
if (sname == NULL)
|
||||
return ("fixlabel: raw partition size > slice size");
|
||||
printf("%s: truncating raw partition\n", sname);
|
||||
pp->p_size = sp->ds_size;
|
||||
}
|
||||
}
|
||||
end = start + sp->ds_size;
|
||||
if (start > end)
|
||||
return ("fixlabel: slice wraps");
|
||||
if (lp->d_secpercyl <= 0)
|
||||
return ("fixlabel: d_secpercyl <= 0");
|
||||
pp -= RAW_PART;
|
||||
warned = FALSE;
|
||||
for (part = 0; part < lp->d_npartitions; part++, pp++) {
|
||||
if (pp->p_offset != 0 || pp->p_size != 0) {
|
||||
if (pp->p_offset < start
|
||||
|| pp->p_offset + pp->p_size > end
|
||||
|| pp->p_offset + pp->p_size < pp->p_offset) {
|
||||
if (sname != NULL) {
|
||||
printf(
|
||||
"%s: rejecting partition in BSD label: it isn't entirely within the slice\n",
|
||||
sname);
|
||||
if (!warned) {
|
||||
slice_info(sname, sp);
|
||||
warned = TRUE;
|
||||
}
|
||||
partition_info(sname, part, pp);
|
||||
}
|
||||
/* XXX else silently discard junk. */
|
||||
bzero(pp, sizeof *pp);
|
||||
} else
|
||||
pp->p_offset += offset;
|
||||
}
|
||||
}
|
||||
lp->d_ncylinders = sp->ds_size / lp->d_secpercyl;
|
||||
lp->d_secperunit = sp->ds_size;
|
||||
lp->d_checksum = 0;
|
||||
lp->d_checksum = dkcksum(lp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
partition_info(sname, part, pp)
|
||||
char *sname;
|
||||
int part;
|
||||
struct partition *pp;
|
||||
{
|
||||
printf("%s%c: start %lu, end %lu, size %lu\n", sname, 'a' + part,
|
||||
(u_long)pp->p_offset, (u_long)(pp->p_offset + pp->p_size - 1),
|
||||
(u_long)pp->p_size);
|
||||
}
|
||||
|
||||
static void
|
||||
slice_info(sname, sp)
|
||||
char *sname;
|
||||
struct diskslice *sp;
|
||||
{
|
||||
printf("%s: start %lu, end %lu, size %lu\n", sname,
|
||||
sp->ds_offset, sp->ds_offset + sp->ds_size - 1, sp->ds_size);
|
||||
}
|
||||
|
||||
static void
|
||||
set_ds_label(ssp, slice, lp)
|
||||
struct diskslices *ssp;
|
||||
int slice;
|
||||
struct disklabel *lp;
|
||||
{
|
||||
ssp->dss_slices[slice].ds_label = lp;
|
||||
if (slice == COMPATIBILITY_SLICE)
|
||||
ssp->dss_slices[ssp->dss_first_bsd_slice].ds_label = lp;
|
||||
else if (slice == ssp->dss_first_bsd_slice)
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_label = lp;
|
||||
}
|
||||
|
||||
static void
|
||||
set_ds_labeldevs(dev, ssp)
|
||||
dev_t dev;
|
||||
struct diskslices *ssp;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_ds_wlabel(ssp, slice, wlabel)
|
||||
struct diskslices *ssp;
|
||||
int slice;
|
||||
int wlabel;
|
||||
{
|
||||
ssp->dss_slices[slice].ds_wlabel = wlabel;
|
||||
if (slice == COMPATIBILITY_SLICE)
|
||||
ssp->dss_slices[ssp->dss_first_bsd_slice].ds_wlabel = wlabel;
|
||||
else if (slice == ssp->dss_first_bsd_slice)
|
||||
ssp->dss_slices[COMPATIBILITY_SLICE].ds_wlabel = wlabel;
|
||||
}
|
||||
#endif
|
@ -1,404 +0,0 @@
|
||||
#ifdef NO_GEOM
|
||||
/*-
|
||||
* Copyright (c) 1994 Bruce D. Evans.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
|
||||
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* PC9801 port by KATO Takenor <kato@eclogite.eps.nagoya-u.ac.jp>
|
||||
*/
|
||||
|
||||
#include "compat_atdisk.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#if defined(PC98) && !defined(PC98_ATCOMPAT)
|
||||
#include <sys/diskpc98.h>
|
||||
#else
|
||||
#include <sys/diskmbr.h>
|
||||
#endif
|
||||
#include <sys/diskslice.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#define TRACE(str) do { if (dsi_debug) printf str; } while (0)
|
||||
|
||||
static volatile u_char dsi_debug;
|
||||
|
||||
|
||||
static int check_part(char *sname, struct pc98_partition *dp,
|
||||
u_long offset, int nsectors, int ntracks,
|
||||
u_long mbr_offset);
|
||||
static int mbr_setslice(char *sname, struct disklabel *lp,
|
||||
struct diskslice *sp, struct pc98_partition *dp,
|
||||
u_long br_offset);
|
||||
|
||||
#define DPBLKNO(cyl,hd,sect) ((cyl)*(lp->d_secpercyl))
|
||||
#if NCOMPAT_ATDISK > 0
|
||||
int atcompat_dsinit(dev_t dev,
|
||||
struct disklabel *lp, struct diskslices **sspp);
|
||||
#endif
|
||||
|
||||
static int
|
||||
check_part(sname, dp, offset, nsectors, ntracks, mbr_offset )
|
||||
char *sname;
|
||||
struct pc98_partition *dp;
|
||||
u_long offset;
|
||||
int nsectors;
|
||||
int ntracks;
|
||||
u_long mbr_offset;
|
||||
{
|
||||
int chs_ecyl;
|
||||
int chs_esect;
|
||||
int chs_scyl;
|
||||
int chs_ssect;
|
||||
int error;
|
||||
u_long esector;
|
||||
u_long esector1;
|
||||
u_long secpercyl;
|
||||
u_long ssector;
|
||||
u_long ssector1;
|
||||
u_long pc98_start;
|
||||
u_long pc98_size;
|
||||
|
||||
secpercyl = (u_long)nsectors * ntracks;
|
||||
chs_scyl = dp->dp_scyl;
|
||||
chs_ssect = dp->dp_ssect;
|
||||
ssector = chs_ssect + dp->dp_shd * nsectors +
|
||||
chs_scyl * secpercyl + mbr_offset;
|
||||
pc98_start = dp->dp_scyl * secpercyl;
|
||||
pc98_size = dp->dp_ecyl ?
|
||||
(dp->dp_ecyl + 1) * secpercyl - pc98_start : 0;
|
||||
ssector1 = offset + pc98_start;
|
||||
|
||||
/*
|
||||
* If ssector1 is on a cylinder >= 1024, then ssector can't be right.
|
||||
* Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct
|
||||
* apart from the cylinder being reduced modulo 1024. Always allow
|
||||
* 1023/255/63.
|
||||
*/
|
||||
if ((ssector < ssector1
|
||||
&& ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1
|
||||
&& chs_scyl == 1023)
|
||||
|| (secpercyl != 0
|
||||
&& (ssector1 - ssector) % (1024 * secpercyl) == 0)))
|
||||
|| (dp->dp_scyl == 255 && dp->dp_shd == 255
|
||||
&& dp->dp_ssect == 255)) {
|
||||
TRACE(("%s: C/H/S start %d/%d/%d, start %lu: allow\n",
|
||||
sname, chs_scyl, dp->dp_shd, chs_ssect, ssector1));
|
||||
ssector = ssector1;
|
||||
}
|
||||
|
||||
chs_ecyl = dp->dp_ecyl;
|
||||
chs_esect = nsectors - 1;
|
||||
esector = chs_esect + (ntracks - 1) * nsectors +
|
||||
chs_ecyl * secpercyl + mbr_offset;
|
||||
esector1 = ssector1 + pc98_size - 1;
|
||||
|
||||
/* Allow certain bogus C/H/S values for esector, as above. */
|
||||
if ((esector < esector1
|
||||
&& ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1
|
||||
&& chs_ecyl == 1023)
|
||||
|| (secpercyl != 0
|
||||
&& (esector1 - esector) % (1024 * secpercyl) == 0)))
|
||||
|| (dp->dp_ecyl == 255 && dp->dp_ehd == 255
|
||||
&& dp->dp_esect == 255)) {
|
||||
TRACE(("%s: C/H/S end %d/%d/%d, end %lu: allow\n",
|
||||
sname, chs_ecyl, dp->dp_ehd, chs_esect, esector1));
|
||||
esector = esector1;
|
||||
}
|
||||
|
||||
error = (ssector == ssector1 && esector == esector1) ? 0 : EINVAL;
|
||||
if (bootverbose)
|
||||
printf("%s: mid 0x%x, start %lu, end = %lu, size %lu%s\n",
|
||||
sname, dp->dp_mid, ssector1, esector1, pc98_size,
|
||||
error ? "" : ": OK");
|
||||
if (ssector != ssector1 && bootverbose)
|
||||
printf("%s: C/H/S start %d/%d/%d (%lu) != start %lu: invalid\n",
|
||||
sname, chs_scyl, dp->dp_shd, chs_ssect,
|
||||
ssector, ssector1);
|
||||
if (esector != esector1 && bootverbose)
|
||||
printf("%s: C/H/S end %d/%d/%d (%lu) != end %lu: invalid\n",
|
||||
sname, chs_ecyl, dp->dp_ehd, chs_esect,
|
||||
esector, esector1);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
dsinit(dev, lp, sspp)
|
||||
dev_t dev;
|
||||
struct disklabel *lp;
|
||||
struct diskslices **sspp;
|
||||
{
|
||||
struct buf *bp;
|
||||
u_char *cp;
|
||||
int dospart;
|
||||
struct pc98_partition *dp;
|
||||
struct pc98_partition *dp0;
|
||||
int error;
|
||||
int max_ncyls;
|
||||
int max_nsectors;
|
||||
int max_ntracks;
|
||||
u_long mbr_offset;
|
||||
char partname[2];
|
||||
u_long secpercyl;
|
||||
char *sname;
|
||||
struct diskslice *sp;
|
||||
struct diskslices *ssp;
|
||||
|
||||
mbr_offset = DOSBBSECTOR;
|
||||
/* Read master boot record. */
|
||||
if ((int)lp->d_secsize < 1024)
|
||||
bp = geteblk((int)1024);
|
||||
else
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
|
||||
bp->b_blkno = mbr_offset;
|
||||
bp->b_bcount = lp->d_secsize;
|
||||
bp->b_iocmd = BIO_READ;
|
||||
if (bp->b_bcount < 1024)
|
||||
bp->b_bcount = 1024;
|
||||
DEV_STRATEGY(bp);
|
||||
if (bufwait(bp) != 0) {
|
||||
disk_err(&bp->b_io, "reading primary partition table: error",
|
||||
0, 1);
|
||||
error = EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Weakly verify it. */
|
||||
cp = bp->b_data;
|
||||
sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART, partname);
|
||||
if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
|
||||
if (bootverbose)
|
||||
printf("%s: invalid primary partition table: no magic\n",
|
||||
sname);
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* entire disk for FreeBSD
|
||||
*/
|
||||
if ((*(cp + 512) == 0x57) && (*(cp + 513) == 0x45) &&
|
||||
(*(cp + 514) == 0x56) && (*(cp + 515) == 0x82)) {
|
||||
sname = dsname(dev, dkunit(dev), BASE_SLICE,
|
||||
RAW_PART, partname);
|
||||
free(*sspp, M_DEVBUF);
|
||||
ssp = dsmakeslicestruct(MAX_SLICES, lp);
|
||||
*sspp = ssp;
|
||||
|
||||
/* Initialize normal slices. */
|
||||
sp = &ssp->dss_slices[BASE_SLICE];
|
||||
sp->ds_offset = 0;
|
||||
sp->ds_size = lp->d_secperunit;
|
||||
sp->ds_type = DOSPTYP_386BSD;
|
||||
sp->ds_subtype = 0xc4;
|
||||
error = 0;
|
||||
ssp->dss_nslices = BASE_SLICE + 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX --- MS-DOG MO
|
||||
*/
|
||||
if ((*(cp + 0x0e) == 1) && (*(cp + 0x15) == 0xf0) &&
|
||||
(*(cp + 0x1c) == 0x0) &&
|
||||
((*(cp + 512) == 0xf0) || (*(cp + 512) == 0xf8)) &&
|
||||
(*(cp + 513) == 0xff) && (*(cp + 514) == 0xff)) {
|
||||
sname = dsname(dev, dkunit(dev), BASE_SLICE,
|
||||
RAW_PART, partname);
|
||||
free(*sspp, M_DEVBUF);
|
||||
ssp = dsmakeslicestruct(MAX_SLICES, lp);
|
||||
*sspp = ssp;
|
||||
|
||||
/* Initialize normal slices. */
|
||||
sp = &ssp->dss_slices[BASE_SLICE];
|
||||
sp->ds_offset = 0;
|
||||
sp->ds_size = lp->d_secperunit;
|
||||
sp->ds_type = 0xa0; /* XXX */
|
||||
sp->ds_subtype = 0x81; /* XXX */
|
||||
error = 0;
|
||||
ssp->dss_nslices = BASE_SLICE + 1;
|
||||
goto done;
|
||||
}
|
||||
#if NCOMPAT_ATDISK > 0
|
||||
/*
|
||||
* Check magic number of 'extended format' for PC-9801.
|
||||
* If no magic, it may be formatted on IBM-PC.
|
||||
*/
|
||||
if (((cp[4] != 'I') || (cp[5] != 'P') || (cp[6] != 'L') ||
|
||||
(cp[7] != '1')) &&
|
||||
((strncmp(devtoname(bp->b_dev), "da", 2) == 0) ||
|
||||
(strncmp(devtoname(bp->b_dev), "wd", 2) == 0) ||
|
||||
(strncmp(devtoname(bp->b_dev), "ad", 2) == 0))) {
|
||||
/* IBM-PC HDD */
|
||||
bp->b_flags |= B_INVAL | B_AGE;
|
||||
brelse(bp);
|
||||
return atcompat_dsinit(dev, lp, sspp);
|
||||
}
|
||||
#endif
|
||||
dp0 = (struct pc98_partition *)(cp + 512);
|
||||
|
||||
/* Guess the geometry. */
|
||||
/*
|
||||
* TODO:
|
||||
* Perhaps skip entries with 0 size.
|
||||
* Perhaps only look at entries of type DOSPTYP_386BSD.
|
||||
*/
|
||||
max_ncyls = 0;
|
||||
max_nsectors = 0;
|
||||
max_ntracks = 0;
|
||||
for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
|
||||
int ncyls;
|
||||
int nsectors;
|
||||
int ntracks;
|
||||
|
||||
|
||||
ncyls = lp->d_ncylinders;
|
||||
if (max_ncyls < ncyls)
|
||||
max_ncyls = ncyls;
|
||||
nsectors = lp->d_nsectors;
|
||||
if (max_nsectors < nsectors)
|
||||
max_nsectors = nsectors;
|
||||
ntracks = lp->d_ntracks;
|
||||
if (max_ntracks < ntracks)
|
||||
max_ntracks = ntracks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we have guessed the geometry right by checking the
|
||||
* partition entries.
|
||||
*/
|
||||
/*
|
||||
* TODO:
|
||||
* As above.
|
||||
* Check for overlaps.
|
||||
* Check against d_secperunit if the latter is reliable.
|
||||
*/
|
||||
error = 0;
|
||||
for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
|
||||
if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0)
|
||||
continue;
|
||||
sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
|
||||
RAW_PART, partname);
|
||||
/*
|
||||
* Temporarily ignore errors from this check. We could
|
||||
* simplify things by accepting the table eariler if we
|
||||
* always ignore errors here. Perhaps we should always
|
||||
* accept the table if the magic is right but not let
|
||||
* bad entries affect the geometry.
|
||||
*/
|
||||
check_part(sname, dp, mbr_offset, max_nsectors, max_ntracks,
|
||||
mbr_offset);
|
||||
}
|
||||
if (error != 0)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Accept the DOS partition table.
|
||||
* First adjust the label (we have been careful not to change it
|
||||
* before we can guarantee success).
|
||||
*/
|
||||
secpercyl = (u_long)max_nsectors * max_ntracks;
|
||||
if (secpercyl != 0) {
|
||||
lp->d_nsectors = max_nsectors;
|
||||
lp->d_ntracks = max_ntracks;
|
||||
lp->d_secpercyl = secpercyl;
|
||||
lp->d_ncylinders = lp->d_secperunit / secpercyl;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are passed a pointer to a suitably initialized minimal
|
||||
* slices "struct" with no dangling pointers in it. Replace it
|
||||
* by a maximal one. This usually oversizes the "struct", but
|
||||
* enlarging it while searching for logical drives would be
|
||||
* inconvenient.
|
||||
*/
|
||||
free(*sspp, M_DEVBUF);
|
||||
ssp = dsmakeslicestruct(MAX_SLICES, lp);
|
||||
*sspp = ssp;
|
||||
|
||||
/* Initialize normal slices. */
|
||||
sp = &ssp->dss_slices[BASE_SLICE];
|
||||
for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++, sp++) {
|
||||
sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
|
||||
RAW_PART, partname);
|
||||
(void)mbr_setslice(sname, lp, sp, dp, mbr_offset);
|
||||
}
|
||||
ssp->dss_nslices = BASE_SLICE + NDOSPART;
|
||||
|
||||
|
||||
done:
|
||||
bp->b_flags |= B_INVAL | B_AGE;
|
||||
brelse(bp);
|
||||
if (error == EINVAL)
|
||||
error = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mbr_setslice(sname, lp, sp, dp, br_offset)
|
||||
char *sname;
|
||||
struct disklabel *lp;
|
||||
struct diskslice *sp;
|
||||
struct pc98_partition *dp;
|
||||
u_long br_offset;
|
||||
{
|
||||
u_long offset;
|
||||
u_long size;
|
||||
|
||||
offset = DPBLKNO(dp->dp_scyl, dp->dp_shd, dp->dp_ssect);
|
||||
size = dp->dp_ecyl ?
|
||||
DPBLKNO(dp->dp_ecyl + 1, dp->dp_ehd, dp->dp_esect) - offset : 0;
|
||||
sp->ds_offset = offset;
|
||||
sp->ds_size = size;
|
||||
sp->ds_type = dp->dp_mid;
|
||||
sp->ds_subtype = dp->dp_sid;
|
||||
strncpy(sp->ds_name, dp->dp_name, sizeof(sp->ds_name));
|
||||
#if 0
|
||||
lp->d_subtype |= (lp->d_subtype & 3) | dospart | DSTYPE_INDOSPART;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user