/FreeBSD/geom_nbsd/trunk/src/Makefile |
---|
1,7 → 1,5 |
# $FreeBSD$ |
.PATH: . |
.PATH: ./src |
KMOD= geom_nbsd |
SRCS= disklabel.h geom_nbsd.c geom_nbsd_enc.c |
/FreeBSD/geom_nbsd/trunk/src/geom_nbsd.c |
---|
1,4 → 1,9 |
/*- |
* Copyright 2005, Anatoli Klassen <anatoli@aksoft.net> |
* All rights reserved. |
* |
* The code is based on code of geom_bsd module by Poul-Henning Kamp. |
* |
* Copyright (c) 2002 Poul-Henning Kamp |
* Copyright (c) 2002 Networks Associates Technology, Inc. |
* All rights reserved. |
39,19 → 44,12 |
* it will serve as the source in future copy&paste operations. |
*/ |
#include <sys/cdefs.h> |
__FBSDID("$FreeBSD: src/sys/geom/geom_bsd.c,v 1.73 2005/03/16 20:48:13 pjd Exp $"); |
#include <sys/param.h> |
#include <sys/endian.h> |
#include <sys/systm.h> |
#include <sys/kernel.h> |
#include <sys/fcntl.h> |
#include <sys/conf.h> |
#include <sys/bio.h> |
#include <sys/malloc.h> |
#include <sys/lock.h> |
#include <sys/mutex.h> |
#include <sys/md5.h> |
#include <sys/errno.h> |
#include <geom/geom.h> |
61,8 → 59,6 |
#define NBSD_CLASS_NAME "NetBSD" |
#define ALPHA_LABEL_OFFSET 64 |
#define LABELSIZE (148 + 16 * NBSD_MAXPARTITIONS) |
/* |
87,36 → 83,31 |
static int |
g_nbsd_modify(struct g_geom *gp, struct g_nbsd_softc *ms) |
{ |
int i, error; |
char useable[NBSD_MAXPARTITIONS]; |
MD5_CTX md5sum; |
struct partition *ppp; |
struct g_slicer *gsp; |
struct g_consumer *cp; |
struct disklabel *dl; |
off_t rawoffset, fullsize, o; |
int i, error; |
u_int secsize, u; |
off_t rawoffset, fullsize, o; |
struct disklabel dl; |
MD5_CTX md5sum; |
char useable[NBSD_MAXPARTITIONS]; |
g_topology_assert(); |
gsp = gp->softc; |
dl = &ms->ondisk; |
/* XXX double work */ |
error = nbsd_disklabel_le_dec(ms->label, &dl, NBSD_MAXPARTITIONS); |
if (error) { |
return (error); |
} |
/* Get dimensions of our device. */ |
cp = LIST_FIRST(&gp->consumer); |
secsize = cp->provider->sectorsize; |
/* ... or a smaller sector size. */ |
if (dl.d_secsize < secsize) { |
if (dl->d_secsize < secsize) { |
return (EINVAL); |
} |
/* ... or a non-multiple sector size. */ |
if (dl.d_secsize % secsize != 0) { |
if (dl->d_secsize % secsize != 0) { |
return (EINVAL); |
} |
123,12 → 114,12 |
rawoffset = ms->mbroffset; |
fullsize = cp->provider->mediasize; |
for (i = 0; i < dl.d_npartitions; i++) { |
ppp = &dl.d_partitions[i]; |
for (i = 0; i < dl->d_npartitions; i++) { |
ppp = &dl->d_partitions[i]; |
/* skip partitions with no type or outside of slide */ |
if (ppp->p_size == 0 || ppp->p_fstype == 0 || |
(off_t)ppp->p_offset * dl.d_secsize < rawoffset || |
(off_t)(ppp->p_offset + ppp->p_size) * dl.d_secsize |
(off_t)ppp->p_offset * dl->d_secsize < rawoffset || |
(off_t)(ppp->p_offset + ppp->p_size) * dl->d_secsize |
> (rawoffset + fullsize)) |
useable[i] = 0; |
else |
136,18 → 127,15 |
} |
/* Don't munge open partitions. */ |
for (i = 0; i < dl.d_npartitions; i++) { |
for (i = 0; i < dl->d_npartitions; i++) { |
if(!useable[i]) continue; |
ppp = &dl.d_partitions[i]; |
o = (off_t)ppp->p_offset * dl.d_secsize; |
ppp = &dl->d_partitions[i]; |
o = (off_t)ppp->p_offset * dl->d_secsize; |
if (o == 0) |
o = rawoffset; |
error = g_slice_config(gp, i, G_SLICE_CONFIG_CHECK, |
o - rawoffset, |
(off_t)ppp->p_size * dl.d_secsize, |
dl.d_secsize, |
o - rawoffset, (off_t)ppp->p_size * dl->d_secsize, dl->d_secsize, |
"%s%c", gp->name, 'a' + i); |
if (error) |
return (error); |
157,19 → 145,18 |
for (u = 0; u < gsp->nslice; u++) { |
if(!useable[u]) continue; |
ppp = &dl.d_partitions[u]; |
o = (off_t)ppp->p_offset * dl.d_secsize; |
ppp = &dl->d_partitions[u]; |
o = (off_t)ppp->p_offset * dl->d_secsize; |
if (o == 0) |
o = rawoffset; |
g_slice_config(gp, u, G_SLICE_CONFIG_SET, |
o - rawoffset, |
(off_t)ppp->p_size * dl.d_secsize, |
dl.d_secsize, |
(off_t)ppp->p_size * dl->d_secsize, |
dl->d_secsize, |
"%s%c", gp->name, 'a' + u); |
} |
/* Update our softc */ |
ms->ondisk = dl; |
ms->rawoffset = rawoffset; |
/* |
193,7 → 180,8 |
*/ |
static int |
g_nbsd_try(struct g_geom *gp, struct g_slicer *gsp, struct g_consumer *cp, int secsize, struct g_nbsd_softc *ms, off_t offset) |
g_nbsd_try(struct g_geom *gp, struct g_slicer *gsp, struct g_consumer *cp, |
int secsize, struct g_nbsd_softc *ms, off_t offset) |
{ |
int error; |
u_char *buf; |
243,23 → 231,8 |
static int |
g_nbsd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) |
{ |
struct g_geom *gp; |
struct g_nbsd_softc *ms; |
struct g_slicer *gsp; |
gp = pp->geom; |
gsp = gp->softc; |
ms = gsp->softc; |
switch(cmd) { |
case DIOCGDINFO: |
/* Return a copy of the disklabel to userland. */ |
nbsd_disklabel_le_dec(ms->label, data, NBSD_MAXPARTITIONS); |
return(0); |
default: |
return (ENOIOCTL); |
} |
} |
static int |
g_nbsd_start(struct bio *bp) |
285,7 → 258,8 |
* consumer and provider. We let g_slice_dumpconf() do most of the work. |
*/ |
static void |
g_nbsd_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp) |
g_nbsd_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, |
struct g_consumer *cp, struct g_provider *pp) |
{ |
struct g_nbsd_softc *ms; |
struct g_slicer *gsp; |
333,14 → 307,14 |
static struct g_geom * |
g_nbsd_taste(struct g_class *mp, struct g_provider *pp, int flags) |
{ |
MD5_CTX md5sum; |
u_char hash[16]; |
struct g_geom *gp; |
struct g_consumer *cp; |
struct g_nbsd_softc *ms; |
struct g_slicer *gsp; |
int error; |
struct g_nbsd_softc *ms; |
u_int secsize; |
struct g_slicer *gsp; |
u_char hash[16]; |
MD5_CTX md5sum; |
g_trace(G_T_TOPOLOGY, "nbsd_taste(%s,%s)", mp->name, pp->name); |
g_topology_assert(); |
/FreeBSD/geom_nbsd/trunk/src/disklabel.h |
---|
1,4 → 1,9 |
/*- |
* Copyright 2005, Anatoli Klassen <anatoli@aksoft.net> |
* All rights reserved. |
* |
* The code is based on code of geom_bsd module by Poul-Henning Kamp. |
* |
* Copyright (c) 1987, 1988, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
27,23 → 32,12 |
* SUCH DAMAGE. |
* |
* @(#)disklabel.h 8.2 (Berkeley) 7/10/94 |
* $FreeBSD: src/sys/sys/disklabel.h,v 1.107 2005/04/07 22:09:02 cognet Exp $ |
*/ |
#ifndef _SYS_DISKLABEL_H_ |
#define _SYS_DISKLABEL_H_ |
#ifndef _NBSD_DISKLABEL_H_ |
#define _NBSD_DISKLABEL_H_ |
#ifndef _KERNEL |
#include <sys/types.h> |
#endif |
#include <sys/ioccom.h> |
/* |
* Disk description table, see disktab(5) |
*/ |
#define _PATH_DISKTAB "/etc/disktab" |
/* |
* Each disk has a label which includes information about the hardware |
* disk geometry, filesystem partitions, and drive specific information. |
* The label is in block 0 or 1, possibly offset from the beginning |
73,10 → 67,6 |
/* Size of bootblock area in sector-size neutral bytes */ |
#define BBSIZE 8192 |
#define LABEL_PART 2 /* partition containing label */ |
#define RAW_PART 2 /* partition containing whole disk */ |
#define SWAP_PART 1 /* partition normally containing swap */ |
struct disklabel { |
u_int32_t d_magic; /* the magic number */ |
u_int16_t d_type; /* drive type */ |
156,145 → 146,11 |
CTASSERT(sizeof(struct disklabel) == 148 + NBSD_MAXPARTITIONS * 16); |
#endif |
static __inline u_int16_t dkcksum(struct disklabel *lp); |
static __inline u_int16_t |
dkcksum(struct disklabel *lp) |
{ |
u_int16_t *start, *end; |
u_int16_t sum = 0; |
start = (u_int16_t *)lp; |
end = (u_int16_t *)&lp->d_partitions[lp->d_npartitions]; |
while (start < end) |
sum ^= *start++; |
return (sum); |
} |
/* d_type values: */ |
#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ |
#define DTYPE_MSCP 2 /* MSCP */ |
#define DTYPE_DEC 3 /* other DEC (rk, rl) */ |
#define DTYPE_SCSI 4 /* SCSI */ |
#define DTYPE_ESDI 5 /* ESDI interface */ |
#define DTYPE_ST506 6 /* ST506 etc. */ |
#define DTYPE_HPIB 7 /* CS/80 on HP-IB */ |
#define DTYPE_HPFL 8 /* HP Fiber-link */ |
#define DTYPE_FLOPPY 10 /* floppy */ |
#define DTYPE_CCD 11 /* concatenated disk */ |
#define DTYPE_VINUM 12 /* vinum volume */ |
#define DTYPE_DOC2K 13 /* Msys DiskOnChip */ |
#define DTYPE_RAID 14 /* CMU RAIDFrame */ |
#define DTYPE_JFS2 16 /* IBM JFS 2 */ |
#ifdef DKTYPENAMES |
static const char *dktypenames[] = { |
"unknown", |
"SMD", |
"MSCP", |
"old DEC", |
"SCSI", |
"ESDI", |
"ST506", |
"HP-IB", |
"HP-FL", |
"type 9", |
"floppy", |
"CCD", |
"Vinum", |
"DOC2K", |
"Raid", |
"?", |
"jfs", |
NULL |
}; |
#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1) |
#endif |
/* |
* Filesystem type and version. |
* Used to interpret other filesystem-specific |
* per-partition information. |
*/ |
#define FS_UNUSED 0 /* unused */ |
#define FS_SWAP 1 /* swap */ |
#define FS_V6 2 /* Sixth Edition */ |
#define FS_V7 3 /* Seventh Edition */ |
#define FS_SYSV 4 /* System V */ |
#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ |
#define FS_V8 6 /* Eighth Edition, 4K blocks */ |
#define FS_BSDFFS 7 /* 4.2BSD fast filesystem */ |
#define FS_MSDOS 8 /* MSDOS filesystem */ |
#define FS_BSDLFS 9 /* 4.4BSD log-structured filesystem */ |
#define FS_OTHER 10 /* in use, but unknown/unsupported */ |
#define FS_HPFS 11 /* OS/2 high-performance filesystem */ |
#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */ |
#define FS_BOOT 13 /* partition contains bootstrap */ |
#define FS_VINUM 14 /* Vinum drive */ |
#define FS_RAID 15 /* RAIDFrame drive */ |
#define FS_JFS2 21 /* IBM JFS2 */ |
#ifdef FSTYPENAMES |
static const char *fstypenames[] = { |
"unused", |
"swap", |
"Version 6", |
"Version 7", |
"System V", |
"4.1BSD", |
"Eighth Edition", |
"4.2BSD", |
"MSDOS", |
"4.4LFS", |
"unknown", |
"HPFS", |
"ISO9660", |
"boot", |
"vinum", |
"raid", |
"?", |
"?", |
"?", |
"?", |
"jfs", |
NULL |
}; |
#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1) |
#endif |
/* |
* flags shared by various drives: |
*/ |
#define D_REMOVABLE 0x01 /* removable media */ |
#define D_ECC 0x02 /* supports ECC */ |
#define D_BADSECT 0x04 /* supports bad sector forw. */ |
#define D_RAMDISK 0x08 /* disk emulator */ |
#define D_CHAIN 0x10 /* can do back-back transfers */ |
/* |
* Disklabel-specific ioctls. |
* |
* NB: <sys/disk.h> defines ioctls from 'd'/128 and up. |
*/ |
/* get and set disklabel */ |
#define DIOCGDINFO _IOR('d', 101, struct disklabel)/* get */ |
#define DIOCSDINFO _IOW('d', 102, struct disklabel)/* set */ |
#define DIOCWDINFO _IOW('d', 103, struct disklabel)/* set, update disk */ |
#define DIOCBSDBB _IOW('d', 110, void *) /* write bootblocks */ |
/* |
* Functions for proper encoding/decoding of struct disklabel into/from |
* bytestring. |
*/ |
void nbsd_partition_le_dec(u_char *ptr, struct partition *d); |
int nbsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart); |
void nbsd_partition_le_enc(u_char *ptr, struct partition *d); |
void nbsd_disklabel_le_enc(u_char *ptr, struct disklabel *d); |
#ifndef _KERNEL |
__BEGIN_DECLS |
struct disklabel *getdiskbyname(const char *); |
__END_DECLS |
#endif |
#endif /* !_SYS_DISKLABEL_H_ */ |
#endif /* !_NBSD_DISKLABEL_H_ */ |
/FreeBSD/geom_nbsd/trunk/src/geom_nbsd_enc.c |
---|
1,4 → 1,9 |
/*- |
* Copyright 2005, Anatoli Klassen <anatoli@aksoft.net> |
* All rights reserved. |
* |
* The code is based on code of geom_bsd module by Poul-Henning Kamp. |
* |
* Copyright (c) 2002 Poul-Henning Kamp |
* Copyright (c) 2002 Networks Associates Technology, Inc. |
* All rights reserved. |
34,23 → 39,16 |
*/ |
/* |
* Functions to encode and decode struct disklabel and struct partition into |
* Functions to decode struct disklabel and struct partition into |
* a bytestream of little endianess and correct packing. |
* |
* NB! This file must be usable both in kernel and userland. |
*/ |
#include <sys/cdefs.h> |
__FBSDID("$FreeBSD: src/sys/geom/geom_bsd_enc.c,v 1.6 2005/01/06 18:27:29 imp Exp $"); |
#include <sys/types.h> |
#include <sys/endian.h> |
#include <sys/errno.h> |
#ifdef _KERNEL |
#include <sys/systm.h> |
#else |
#include <string.h> |
#endif |
#include "disklabel.h" |
82,6 → 80,9 |
} |
d->d_npartitions = le16dec(ptr + 138); |
if (maxpart > NBSD_MAXPARTITIONS) { |
return(EINVAL); |
} |
if (d->d_npartitions > maxpart) { |
return(EINVAL); |
} |
128,70 → 129,8 |
d->d_npartitions = le16dec(ptr + 138); |
d->d_bbsize = le32dec(ptr + 140); |
d->d_sbsize = le32dec(ptr + 144); |
for (i = 0; i < NBSD_MAXPARTITIONS; i++) |
for (i = 0; i < d->d_npartitions; i++) |
nbsd_partition_le_dec(ptr + 148 + 16 * i, &d->d_partitions[i]); |
return(0); |
} |
void |
nbsd_partition_le_enc(u_char *ptr, struct partition *d) |
{ |
le32enc(ptr + 0, d->p_size); |
le32enc(ptr + 4, d->p_offset); |
le32enc(ptr + 8, d->p_fsize); |
ptr[12] = d->p_fstype; |
ptr[13] = d->p_frag; |
le16enc(ptr + 14, d->p_cpg); |
} |
void |
nbsd_disklabel_le_enc(u_char *ptr, struct disklabel *d) |
{ |
int i; |
u_char *p, *pe; |
uint16_t sum; |
le32enc(ptr + 0, d->d_magic); |
le16enc(ptr + 4, d->d_type); |
le16enc(ptr + 6, d->d_subtype); |
bcopy(d->d_typename, ptr + 8, 16); |
bcopy(d->d_packname, ptr + 24, 16); |
le32enc(ptr + 40, d->d_secsize); |
le32enc(ptr + 44, d->d_nsectors); |
le32enc(ptr + 48, d->d_ntracks); |
le32enc(ptr + 52, d->d_ncylinders); |
le32enc(ptr + 56, d->d_secpercyl); |
le32enc(ptr + 60, d->d_secperunit); |
le16enc(ptr + 64, d->d_sparespertrack); |
le16enc(ptr + 66, d->d_sparespercyl); |
le32enc(ptr + 68, d->d_acylinders); |
le16enc(ptr + 72, d->d_rpm); |
le16enc(ptr + 74, d->d_interleave); |
le16enc(ptr + 76, d->d_trackskew); |
le16enc(ptr + 78, d->d_cylskew); |
le32enc(ptr + 80, d->d_headswitch); |
le32enc(ptr + 84, d->d_trkseek); |
le32enc(ptr + 88, d->d_flags); |
le32enc(ptr + 92, d->d_drivedata[0]); |
le32enc(ptr + 96, d->d_drivedata[1]); |
le32enc(ptr + 100, d->d_drivedata[2]); |
le32enc(ptr + 104, d->d_drivedata[3]); |
le32enc(ptr + 108, d->d_drivedata[4]); |
le32enc(ptr + 112, d->d_spare[0]); |
le32enc(ptr + 116, d->d_spare[1]); |
le32enc(ptr + 120, d->d_spare[2]); |
le32enc(ptr + 124, d->d_spare[3]); |
le32enc(ptr + 128, d->d_spare[4]); |
le32enc(ptr + 132, d->d_magic2); |
le16enc(ptr + 136, 0); |
le16enc(ptr + 138, d->d_npartitions); |
le32enc(ptr + 140, d->d_bbsize); |
le32enc(ptr + 144, d->d_sbsize); |
for (i = 0; i < d->d_npartitions; i++) |
nbsd_partition_le_enc(ptr + 148 + 16 * i, &d->d_partitions[i]); |
pe = ptr + 148 + 16 * d->d_npartitions; |
sum = 0; |
for (p = ptr; p < pe; p += 2) |
sum ^= le16dec(p); |
le16enc(ptr + 136, sum); |
} |