svn commit: r189935 - in stable/7/sys: . contrib/pf dev/ata
dev/ath/ath_hal dev/cxgb geom geom/part
modules/geom/geom_part modules/geom/geom_part/geom_part_ebr sys
Marcel Moolenaar
marcel at FreeBSD.org
Tue Mar 17 12:38:44 PDT 2009
Author: marcel
Date: Tue Mar 17 19:38:40 2009
New Revision: 189935
URL: http://svn.freebsd.org/changeset/base/189935
Log:
Sync gpart with the trunk. This includes:
o APM scheme supports Tivo Series 1 partitions (read only).
o Bootcode support added to BSD scheme.
o New EBR scheme to support Extended Boot Records (logical partitions).
o PC98 scheme fixes (credits to nyan@)
o VTOC8 scheme fixes (credits to marius@)
Added:
stable/7/sys/geom/part/g_part_ebr.c
- copied, changed from r188354, head/sys/geom/part/g_part_ebr.c
stable/7/sys/modules/geom/geom_part/geom_part_ebr/
- copied from r188354, head/sys/modules/geom/geom_part/geom_part_ebr/
Modified:
stable/7/sys/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/dev/ata/atapi-cd.c
stable/7/sys/dev/ath/ath_hal/ (props changed)
stable/7/sys/dev/cxgb/ (props changed)
stable/7/sys/geom/geom.h
stable/7/sys/geom/geom_dev.c
stable/7/sys/geom/geom_subr.c
stable/7/sys/geom/part/g_part.c
stable/7/sys/geom/part/g_part.h
stable/7/sys/geom/part/g_part_apm.c
stable/7/sys/geom/part/g_part_bsd.c
stable/7/sys/geom/part/g_part_gpt.c
stable/7/sys/geom/part/g_part_if.m
stable/7/sys/geom/part/g_part_mbr.c
stable/7/sys/geom/part/g_part_pc98.c
stable/7/sys/geom/part/g_part_vtoc8.c
stable/7/sys/modules/geom/geom_part/Makefile
stable/7/sys/sys/disk.h
stable/7/sys/sys/diskpc98.h
Modified: stable/7/sys/dev/ata/atapi-cd.c
==============================================================================
--- stable/7/sys/dev/ata/atapi-cd.c Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/dev/ata/atapi-cd.c Tue Mar 17 19:38:40 2009 (r189935)
@@ -218,7 +218,10 @@ acd_geom_ioctl(struct g_provider *pp, u_
case CDIOCRESET:
acd_test_ready(dev);
break;
-
+
+ case DIOCGPROVIDERALIAS:
+ break;
+
default:
acd_read_toc(dev);
acd_prevent_allow(dev, 1);
Modified: stable/7/sys/geom/geom.h
==============================================================================
--- stable/7/sys/geom/geom.h Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/geom/geom.h Tue Mar 17 19:38:40 2009 (r189935)
@@ -227,10 +227,11 @@ void g_error_provider(struct g_provider
struct g_provider *g_provider_by_name(char const *arg);
int g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len);
#define g_getattr(a, c, v) g_getattr__((a), (c), (v), sizeof *(v))
-int g_handleattr(struct bio *bp, const char *attribute, void *val, int len);
+int g_handleattr(struct bio *bp, const char *attribute, const void *val,
+ int len);
int g_handleattr_int(struct bio *bp, const char *attribute, int val);
int g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val);
-int g_handleattr_str(struct bio *bp, const char *attribute, char *str);
+int g_handleattr_str(struct bio *bp, const char *attribute, const char *str);
struct g_consumer * g_new_consumer(struct g_geom *gp);
struct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...);
struct g_provider * g_new_providerf(struct g_geom *gp, const char *fmt, ...);
Modified: stable/7/sys/geom/geom_dev.c
==============================================================================
--- stable/7/sys/geom/geom_dev.c Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/geom/geom_dev.c Tue Mar 17 19:38:40 2009 (r189935)
@@ -124,6 +124,7 @@ g_dev_taste(struct g_class *mp, struct g
{
struct g_geom *gp;
struct g_consumer *cp;
+ char *alias;
int error;
struct cdev *dev;
u_int unit;
@@ -147,6 +148,17 @@ g_dev_taste(struct g_class *mp, struct g
gp->softc = dev;
dev->si_drv1 = gp;
dev->si_drv2 = cp;
+
+ g_topology_unlock();
+
+ alias = g_malloc(MAXPATHLEN, M_WAITOK | M_ZERO);
+ error = (pp->geom->ioctl == NULL) ? ENODEV :
+ pp->geom->ioctl(pp, DIOCGPROVIDERALIAS, alias, 0, curthread);
+ if (!error && alias[0] != '\0')
+ make_dev_alias(dev, "%s", alias);
+ g_free(alias);
+
+ g_topology_lock();
return (gp);
}
Modified: stable/7/sys/geom/geom_subr.c
==============================================================================
--- stable/7/sys/geom/geom_subr.c Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/geom/geom_subr.c Tue Mar 17 19:38:40 2009 (r189935)
@@ -856,14 +856,14 @@ g_handleattr_off_t(struct bio *bp, const
}
int
-g_handleattr_str(struct bio *bp, const char *attribute, char *str)
+g_handleattr_str(struct bio *bp, const char *attribute, const char *str)
{
return (g_handleattr(bp, attribute, str, 0));
}
int
-g_handleattr(struct bio *bp, const char *attribute, void *val, int len)
+g_handleattr(struct bio *bp, const char *attribute, const void *val, int len)
{
int error = 0;
@@ -880,12 +880,13 @@ g_handleattr(struct bio *bp, const char
}
} else if (bp->bio_length == len) {
bcopy(val, bp->bio_data, len);
- bp->bio_completed = len;
} else {
printf("%s: %s bio_length %jd len %d -> EFAULT\n", __func__,
bp->bio_to->name, (intmax_t)bp->bio_length, len);
error = EFAULT;
}
+ if (error == 0)
+ bp->bio_completed = bp->bio_length;
g_io_deliver(bp, error);
return (1);
}
Modified: stable/7/sys/geom/part/g_part.c
==============================================================================
--- stable/7/sys/geom/part/g_part.c Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/geom/part/g_part.c Tue Mar 17 19:38:40 2009 (r189935)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2005-2008 Marcel Moolenaar
+ * Copyright (c) 2002, 2005-2009 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bio.h>
+#include <sys/disk.h>
#include <sys/diskmbr.h>
#include <sys/endian.h>
#include <sys/kernel.h>
@@ -86,6 +87,7 @@ static g_taste_t g_part_taste;
static g_access_t g_part_access;
static g_dumpconf_t g_part_dumpconf;
+static g_ioctl_t g_part_ioctl;
static g_orphan_t g_part_orphan;
static g_spoiled_t g_part_spoiled;
static g_start_t g_part_start;
@@ -102,6 +104,7 @@ static struct g_class g_part_class = {
/* Geom methods. */
.access = g_part_access,
.dumpconf = g_part_dumpconf,
+ .ioctl = g_part_ioctl,
.orphan = g_part_orphan,
.spoiled = g_part_spoiled,
.start = g_part_start,
@@ -109,23 +112,6 @@ static struct g_class g_part_class = {
DECLARE_GEOM_CLASS(g_part_class, g_part);
-enum g_part_ctl {
- G_PART_CTL_NONE,
- G_PART_CTL_ADD,
- G_PART_CTL_BOOTCODE,
- G_PART_CTL_COMMIT,
- G_PART_CTL_CREATE,
- G_PART_CTL_DELETE,
- G_PART_CTL_DESTROY,
- G_PART_CTL_MODIFY,
- G_PART_CTL_MOVE,
- G_PART_CTL_RECOVER,
- G_PART_CTL_RESIZE,
- G_PART_CTL_SET,
- G_PART_CTL_UNDO,
- G_PART_CTL_UNSET
-};
-
/*
* Support functions.
*/
@@ -181,10 +167,8 @@ g_part_geometry(struct g_part_table *tab
u_int heads, sectors;
int idx;
- if (g_getattr("GEOM::fwsectors", cp, §ors) != 0 ||
- sectors < 1 || sectors > 63 ||
- g_getattr("GEOM::fwheads", cp, &heads) != 0 ||
- heads < 1 || heads > 255) {
+ if (g_getattr("GEOM::fwsectors", cp, §ors) != 0 || sectors == 0 ||
+ g_getattr("GEOM::fwheads", cp, &heads) != 0 || heads == 0) {
table->gpt_fixgeom = 0;
table->gpt_heads = 0;
table->gpt_sectors = 0;
@@ -245,7 +229,8 @@ g_part_new_entry(struct g_part_table *ta
LIST_INSERT_HEAD(&table->gpt_entry, entry, gpe_entry);
else
LIST_INSERT_AFTER(last, entry, gpe_entry);
- }
+ } else
+ entry->gpe_offset = 0;
entry->gpe_start = start;
entry->gpe_end = end;
return (entry);
@@ -258,11 +243,14 @@ g_part_new_provider(struct g_geom *gp, s
char buf[32];
struct g_consumer *cp;
struct g_provider *pp;
+ off_t offset;
cp = LIST_FIRST(&gp->consumer);
pp = cp->provider;
- entry->gpe_offset = entry->gpe_start * pp->sectorsize;
+ offset = entry->gpe_start * pp->sectorsize;
+ if (entry->gpe_offset < offset)
+ entry->gpe_offset = offset;
if (entry->gpe_pp == NULL) {
entry->gpe_pp = g_new_providerf(gp, "%s%s", gp->name,
@@ -272,6 +260,7 @@ g_part_new_provider(struct g_geom *gp, s
entry->gpe_pp->index = entry->gpe_index - 1; /* index is 1-based. */
entry->gpe_pp->mediasize = (entry->gpe_end - entry->gpe_start + 1) *
pp->sectorsize;
+ entry->gpe_pp->mediasize -= entry->gpe_offset - offset;
entry->gpe_pp->sectorsize = pp->sectorsize;
entry->gpe_pp->flags = pp->flags & G_PF_CANDELETE;
if (pp->stripesize > 0) {
@@ -534,8 +523,8 @@ g_part_ctl_bootcode(struct gctl_req *req
error = ENODEV;
goto fail;
}
- if (gpp->gpp_codesize != sz) {
- error = EINVAL;
+ if (gpp->gpp_codesize > sz) {
+ error = EFBIG;
goto fail;
}
@@ -579,6 +568,8 @@ g_part_ctl_commit(struct gctl_req *req,
return (EPERM);
}
+ g_topology_unlock();
+
cp = LIST_FIRST(&gp->consumer);
if ((table->gpt_smhead | table->gpt_smtail) != 0) {
pp = cp->provider;
@@ -607,6 +598,7 @@ g_part_ctl_commit(struct gctl_req *req,
}
if (table->gpt_scheme == &g_part_null_scheme) {
+ g_topology_lock();
g_access(cp, -1, -1, -1);
g_part_wither(gp, ENXIO);
return (0);
@@ -627,10 +619,13 @@ g_part_ctl_commit(struct gctl_req *req,
}
table->gpt_created = 0;
table->gpt_opened = 0;
+
+ g_topology_lock();
g_access(cp, -1, -1, -1);
return (0);
fail:
+ g_topology_lock();
gctl_error(req, "%d", error);
return (error);
}
@@ -714,14 +709,6 @@ g_part_ctl_create(struct gctl_req *req,
error = g_getattr("PART::depth", cp, &attr);
table->gpt_depth = (!error) ? attr + 1 : 0;
- /* If we're nested, get the absolute sector offset on disk. */
- if (table->gpt_depth) {
- error = g_getattr("PART::offset", cp, &attr);
- if (error)
- goto fail;
- table->gpt_offset = attr;
- }
-
/*
* Synthesize a disk geometry. Some partitioning schemes
* depend on it and since some file systems need it even
@@ -1345,7 +1332,7 @@ g_part_ctlreq(struct gctl_req *req, stru
/* Obtain permissions if possible/necessary. */
close_on_error = 0;
- table = NULL; /* Suppress uninit. warning. */
+ table = NULL;
if (modifies && (gpp.gpp_parms & G_PART_PARM_GEOM)) {
table = gpp.gpp_geom->softc;
if (table != NULL && !table->gpt_opened) {
@@ -1361,7 +1348,16 @@ g_part_ctlreq(struct gctl_req *req, stru
}
}
- error = EDOOFUS; /* Prevent bogus uninit. warning. */
+ /* Allow the scheme to check or modify the parameters. */
+ if (table != NULL) {
+ error = G_PART_PRECHECK(table, ctlreq, &gpp);
+ if (error) {
+ gctl_error(req, "%d pre-check failed", error);
+ goto out;
+ }
+ } else
+ error = EDOOFUS; /* Prevent bogus uninit. warning. */
+
switch (ctlreq) {
case G_PART_CTL_NONE:
panic("%s", __func__);
@@ -1417,6 +1413,7 @@ g_part_ctlreq(struct gctl_req *req, stru
}
}
+ out:
if (error && close_on_error) {
g_access(LIST_FIRST(&gpp.gpp_geom->consumer), -1, -1, -1);
table->gpt_opened = 0;
@@ -1442,6 +1439,7 @@ g_part_taste(struct g_class *mp, struct
struct g_geom *gp;
struct g_part_entry *entry;
struct g_part_table *table;
+ struct root_hold_token *rht;
int attr, depth;
int error;
@@ -1463,6 +1461,7 @@ g_part_taste(struct g_class *mp, struct
return (NULL);
}
+ rht = root_mount_hold(mp->name);
g_topology_unlock();
/*
@@ -1489,14 +1488,6 @@ g_part_taste(struct g_class *mp, struct
table = gp->softc;
- /* If we're nested, get the absolute sector offset on disk. */
- if (table->gpt_depth) {
- error = g_getattr("PART::offset", cp, &attr);
- if (error)
- goto fail;
- table->gpt_offset = attr;
- }
-
/*
* Synthesize a disk geometry. Some partitioning schemes
* depend on it and since some file systems need it even
@@ -1515,11 +1506,13 @@ g_part_taste(struct g_class *mp, struct
g_part_new_provider(gp, table, entry);
}
+ root_mount_rel(rht);
g_access(cp, -1, 0, 0);
return (gp);
fail:
g_topology_lock();
+ root_mount_rel(rht);
g_access(cp, -1, 0, 0);
g_part_wither(gp, error);
return (NULL);
@@ -1576,6 +1569,10 @@ g_part_dumpconf(struct sbuf *sb, const c
entry = pp->private;
if (entry == NULL)
return;
+ sbuf_printf(sb, "%s<start>%ju</start>\n", indent,
+ (uintmax_t)entry->gpe_start);
+ sbuf_printf(sb, "%s<end>%ju</end>\n", indent,
+ (uintmax_t)entry->gpe_end);
sbuf_printf(sb, "%s<index>%u</index>\n", indent,
entry->gpe_index);
sbuf_printf(sb, "%s<type>%s</type>\n", indent,
@@ -1602,6 +1599,31 @@ g_part_dumpconf(struct sbuf *sb, const c
}
}
+static int
+g_part_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag,
+ struct thread *td)
+{
+ struct g_geom *gp;
+ struct g_part_table *table;
+ struct g_part_entry *entry;
+ int error;
+
+ gp = pp->geom;
+ table = gp->softc;
+ entry = pp->private;
+
+ switch (cmd) {
+ case DIOCGPROVIDERALIAS:
+ error = G_PART_DEVALIAS(table, entry, data, MAXPATHLEN);
+ break;
+ default:
+ error = ENOTTY;
+ break;
+ }
+
+ return (error);
+}
+
static void
g_part_orphan(struct g_consumer *cp)
{
@@ -1681,8 +1703,8 @@ g_part_start(struct bio *bp)
return;
if (g_handleattr_int(bp, "PART::depth", table->gpt_depth))
return;
- if (g_handleattr_int(bp, "PART::offset",
- table->gpt_offset + entry->gpe_start))
+ if (g_handleattr_str(bp, "PART::scheme",
+ table->gpt_scheme->name))
return;
if (!strcmp("GEOM::kerneldump", bp->bio_attribute)) {
/*
@@ -1722,7 +1744,7 @@ static void
g_part_init(struct g_class *mp)
{
- TAILQ_INSERT_TAIL(&g_part_schemes, &g_part_null_scheme, scheme_list);
+ TAILQ_INSERT_HEAD(&g_part_schemes, &g_part_null_scheme, scheme_list);
}
static void
Modified: stable/7/sys/geom/part/g_part.h
==============================================================================
--- stable/7/sys/geom/part/g_part.h Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/geom/part/g_part.h Tue Mar 17 19:38:40 2009 (r189935)
@@ -103,13 +103,6 @@ struct g_part_table {
*/
uint32_t gpt_sectors;
uint32_t gpt_heads;
- /*
- * gpt_offset holds the absolute block address of the scheme
- * on disk. Some partitioning schemes (historically) use
- * absolute addressing. Relative addresses are obtained by
- * subtracting gpt_offset from the absolute addresses.
- */
- uint64_t gpt_offset;
int gpt_depth; /* Sub-partitioning level. */
int gpt_isleaf:1; /* Cannot be sub-partitioned. */
@@ -122,6 +115,23 @@ struct g_part_table {
struct g_part_entry *g_part_new_entry(struct g_part_table *, int, quad_t,
quad_t);
+enum g_part_ctl {
+ G_PART_CTL_NONE,
+ G_PART_CTL_ADD,
+ G_PART_CTL_BOOTCODE,
+ G_PART_CTL_COMMIT,
+ G_PART_CTL_CREATE,
+ G_PART_CTL_DELETE,
+ G_PART_CTL_DESTROY,
+ G_PART_CTL_MODIFY,
+ G_PART_CTL_MOVE,
+ G_PART_CTL_RECOVER,
+ G_PART_CTL_RESIZE,
+ G_PART_CTL_SET,
+ G_PART_CTL_UNDO,
+ G_PART_CTL_UNSET
+};
+
/* G_PART ctlreq parameters. */
#define G_PART_PARM_ENTRIES 0x0001
#define G_PART_PARM_FLAGS 0x0002
Modified: stable/7/sys/geom/part/g_part_apm.c
==============================================================================
--- stable/7/sys/geom/part/g_part_apm.c Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/geom/part/g_part_apm.c Tue Mar 17 19:38:40 2009 (r189935)
@@ -50,6 +50,7 @@ struct g_part_apm_table {
struct g_part_table base;
struct apm_ddr ddr;
struct apm_ent self;
+ int tivo_series1;
};
struct g_part_apm_entry {
@@ -61,12 +62,12 @@ static int g_part_apm_add(struct g_part_
struct g_part_parms *);
static int g_part_apm_create(struct g_part_table *, struct g_part_parms *);
static int g_part_apm_destroy(struct g_part_table *, struct g_part_parms *);
-static int g_part_apm_dumpconf(struct g_part_table *, struct g_part_entry *,
+static void g_part_apm_dumpconf(struct g_part_table *, struct g_part_entry *,
struct sbuf *, const char *);
static int g_part_apm_dumpto(struct g_part_table *, struct g_part_entry *);
static int g_part_apm_modify(struct g_part_table *, struct g_part_entry *,
struct g_part_parms *);
-static char *g_part_apm_name(struct g_part_table *, struct g_part_entry *,
+static const char *g_part_apm_name(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_apm_probe(struct g_part_table *, struct g_consumer *);
static int g_part_apm_read(struct g_part_table *, struct g_consumer *);
@@ -99,6 +100,19 @@ static struct g_part_scheme g_part_apm_s
};
G_PART_SCHEME_DECLARE(g_part_apm);
+static void
+swab(char *buf, size_t bufsz)
+{
+ int i;
+ char ch;
+
+ for (i = 0; i < bufsz; i += 2) {
+ ch = buf[i];
+ buf[i] = buf[i + 1];
+ buf[i + 1] = ch;
+ }
+}
+
static int
apm_parse_type(const char *type, char *buf, size_t bufsz)
{
@@ -143,7 +157,8 @@ apm_parse_type(const char *type, char *b
}
static int
-apm_read_ent(struct g_consumer *cp, uint32_t blk, struct apm_ent *ent)
+apm_read_ent(struct g_consumer *cp, uint32_t blk, struct apm_ent *ent,
+ int tivo_series1)
{
struct g_provider *pp;
char *buf;
@@ -153,6 +168,8 @@ apm_read_ent(struct g_consumer *cp, uint
buf = g_read_data(cp, pp->sectorsize * blk, pp->sectorsize, &error);
if (buf == NULL)
return (error);
+ if (tivo_series1)
+ swab(buf, pp->sectorsize);
ent->ent_sig = be16dec(buf);
ent->ent_pmblkcnt = be32dec(buf + 4);
ent->ent_start = be32dec(buf + 8);
@@ -231,7 +248,7 @@ g_part_apm_destroy(struct g_part_table *
return (0);
}
-static int
+static void
g_part_apm_dumpconf(struct g_part_table *table, struct g_part_entry *baseentry,
struct sbuf *sb, const char *indent)
{
@@ -256,7 +273,6 @@ g_part_apm_dumpconf(struct g_part_table
} else {
/* confxml: scheme information */
}
- return (0);
}
static int
@@ -294,7 +310,7 @@ g_part_apm_modify(struct g_part_table *b
return (0);
}
-static char *
+static const char *
g_part_apm_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
{
@@ -316,6 +332,7 @@ g_part_apm_probe(struct g_part_table *ba
return (ENXIO);
table = (struct g_part_apm_table *)basetable;
+ table->tivo_series1 = 0;
pp = cp->provider;
/* Sanity-check the provider. */
@@ -326,17 +343,35 @@ g_part_apm_probe(struct g_part_table *ba
buf = g_read_data(cp, 0L, pp->sectorsize, &error);
if (buf == NULL)
return (error);
- table->ddr.ddr_sig = be16dec(buf);
- table->ddr.ddr_blksize = be16dec(buf + 2);
- table->ddr.ddr_blkcount = be32dec(buf + 4);
- g_free(buf);
- if (table->ddr.ddr_sig != APM_DDR_SIG)
- return (ENXIO);
- if (table->ddr.ddr_blksize != pp->sectorsize)
- return (ENXIO);
+ if (be16dec(buf) == be16toh(APM_DDR_SIG)) {
+ /* Normal Apple DDR */
+ table->ddr.ddr_sig = be16dec(buf);
+ table->ddr.ddr_blksize = be16dec(buf + 2);
+ table->ddr.ddr_blkcount = be32dec(buf + 4);
+ g_free(buf);
+ if (table->ddr.ddr_blksize != pp->sectorsize)
+ return (ENXIO);
+ } else {
+ /*
+ * Check for Tivo drives, which have no DDR and a different
+ * signature. Those whose first two bytes are 14 92 are
+ * Series 2 drives, and aren't supported. Those that start
+ * with 92 14 are series 1 drives and are supported.
+ */
+ if (be16dec(buf) != 0x9214) {
+ /* If this is 0x1492 it could be a series 2 drive */
+ g_free(buf);
+ return (ENXIO);
+ }
+ table->ddr.ddr_sig = APM_DDR_SIG; /* XXX */
+ table->ddr.ddr_blksize = pp->sectorsize; /* XXX */
+ table->ddr.ddr_blkcount = pp->mediasize / pp->sectorsize;/* XXX */
+ table->tivo_series1 = 1;
+ g_free(buf);
+ }
/* Check that there's a Partition Map. */
- error = apm_read_ent(cp, 1, &table->self);
+ error = apm_read_ent(cp, 1, &table->self, table->tivo_series1);
if (error)
return (error);
if (table->self.ent_sig != APM_ENT_SIG)
@@ -363,7 +398,7 @@ g_part_apm_read(struct g_part_table *bas
basetable->gpt_entries = table->self.ent_pmblkcnt - 1;
for (index = table->self.ent_pmblkcnt - 1; index > 0; index--) {
- error = apm_read_ent(cp, index + 1, &ent);
+ error = apm_read_ent(cp, index + 1, &ent, table->tivo_series1);
if (error)
continue;
if (!strcmp(ent.ent_type, APM_ENT_TYPE_UNUSED))
@@ -413,6 +448,11 @@ g_part_apm_write(struct g_part_table *ba
int error, index;
table = (struct g_part_apm_table *)basetable;
+ /*
+ * Tivo Series 1 disk partitions are currently read-only.
+ */
+ if (table->tivo_series1)
+ return (EOPNOTSUPP);
bzero(buf, sizeof(buf));
/* Write the DDR and 'self' entry only when we're newly created. */
Modified: stable/7/sys/geom/part/g_part_bsd.c
==============================================================================
--- stable/7/sys/geom/part/g_part_bsd.c Tue Mar 17 19:37:47 2009 (r189934)
+++ stable/7/sys/geom/part/g_part_bsd.c Tue Mar 17 19:38:40 2009 (r189935)
@@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
struct g_part_bsd_table {
struct g_part_table base;
- u_char *label;
+ u_char *bbarea;
uint32_t offset;
};
@@ -58,14 +58,15 @@ struct g_part_bsd_entry {
static int g_part_bsd_add(struct g_part_table *, struct g_part_entry *,
struct g_part_parms *);
+static int g_part_bsd_bootcode(struct g_part_table *, struct g_part_parms *);
static int g_part_bsd_create(struct g_part_table *, struct g_part_parms *);
static int g_part_bsd_destroy(struct g_part_table *, struct g_part_parms *);
-static int g_part_bsd_dumpconf(struct g_part_table *, struct g_part_entry *,
+static void g_part_bsd_dumpconf(struct g_part_table *, struct g_part_entry *,
struct sbuf *, const char *);
static int g_part_bsd_dumpto(struct g_part_table *, struct g_part_entry *);
static int g_part_bsd_modify(struct g_part_table *, struct g_part_entry *,
struct g_part_parms *);
-static char *g_part_bsd_name(struct g_part_table *, struct g_part_entry *,
+static const char *g_part_bsd_name(struct g_part_table *, struct g_part_entry *,
char *, size_t);
static int g_part_bsd_probe(struct g_part_table *, struct g_consumer *);
static int g_part_bsd_read(struct g_part_table *, struct g_consumer *);
@@ -75,6 +76,7 @@ static int g_part_bsd_write(struct g_par
static kobj_method_t g_part_bsd_methods[] = {
KOBJMETHOD(g_part_add, g_part_bsd_add),
+ KOBJMETHOD(g_part_bootcode, g_part_bsd_bootcode),
KOBJMETHOD(g_part_create, g_part_bsd_create),
KOBJMETHOD(g_part_destroy, g_part_bsd_destroy),
KOBJMETHOD(g_part_dumpconf, g_part_bsd_dumpconf),
@@ -95,6 +97,7 @@ static struct g_part_scheme g_part_bsd_s
.gps_entrysz = sizeof(struct g_part_bsd_entry),
.gps_minent = 8,
.gps_maxent = 20,
+ .gps_bootcodesz = BBSIZE,
};
G_PART_SCHEME_DECLARE(g_part_bsd);
@@ -157,6 +160,30 @@ g_part_bsd_add(struct g_part_table *base
}
static int
+g_part_bsd_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp)
+{
+ struct g_part_bsd_table *table;
+ const u_char *codeptr;
+ size_t hdsz, tlsz;
+ size_t codesz, tlofs;
+
+ hdsz = 512;
+ tlofs = hdsz + 148 + basetable->gpt_entries * 16;
+ tlsz = BBSIZE - tlofs;
+ table = (struct g_part_bsd_table *)basetable;
+ bzero(table->bbarea, hdsz);
+ bzero(table->bbarea + tlofs, tlsz);
+ codeptr = gpp->gpp_codeptr;
+ codesz = MIN(hdsz, gpp->gpp_codesize);
+ if (codesz > 0)
+ bcopy(codeptr, table->bbarea, codesz);
+ codesz = MIN(tlsz, gpp->gpp_codesize - tlofs);
+ if (codesz > 0)
+ bcopy(codeptr + tlofs, table->bbarea + tlofs, codesz);
+ return (0);
+}
+
+static int
g_part_bsd_create(struct g_part_table *basetable, struct g_part_parms *gpp)
{
struct g_consumer *cp;
@@ -173,13 +200,16 @@ g_part_bsd_create(struct g_part_table *b
if (pp->sectorsize < sizeof(struct disklabel))
return (ENOSPC);
+ if (BBSIZE % pp->sectorsize)
+ return (ENOTBLK);
msize = pp->mediasize / pp->sectorsize;
secpercyl = basetable->gpt_sectors * basetable->gpt_heads;
ncyls = msize / secpercyl;
table = (struct g_part_bsd_table *)basetable;
- ptr = table->label = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO);
+ table->bbarea = g_malloc(BBSIZE, M_WAITOK | M_ZERO);
+ ptr = table->bbarea + pp->sectorsize;
le32enc(ptr + 0, DISKMAGIC); /* d_magic */
le32enc(ptr + 40, pp->sectorsize); /* d_secsize */
@@ -216,7 +246,7 @@ g_part_bsd_destroy(struct g_part_table *
return (0);
}
-static int
+static void
g_part_bsd_dumpconf(struct g_part_table *table, struct g_part_entry *baseentry,
struct sbuf *sb, const char *indent)
{
@@ -233,7 +263,6 @@ g_part_bsd_dumpconf(struct g_part_table
} else {
/* confxml: scheme information */
}
- return (0);
}
static int
@@ -241,9 +270,10 @@ g_part_bsd_dumpto(struct g_part_table *t
{
struct g_part_bsd_entry *entry;
- /* Allow dumping to a swap partition only. */
+ /* Allow dumping to a swap partition or an unused partition. */
entry = (struct g_part_bsd_entry *)baseentry;
- return ((entry->part.p_fstype == FS_SWAP) ? 1 : 0);
+ return ((entry->part.p_fstype == FS_UNUSED ||
+ entry->part.p_fstype == FS_SWAP) ? 1 : 0);
}
static int
@@ -261,7 +291,7 @@ g_part_bsd_modify(struct g_part_table *b
return (0);
}
-static char *
+static const char *
g_part_bsd_name(struct g_part_table *table, struct g_part_entry *baseentry,
char *buf, size_t bufsz)
{
@@ -284,6 +314,8 @@ g_part_bsd_probe(struct g_part_table *ta
if (pp->sectorsize < sizeof(struct disklabel) ||
pp->mediasize < BBSIZE)
return (ENOSPC);
+ if (BBSIZE % pp->sectorsize)
+ return (ENOTBLK);
/* Check that there's a disklabel. */
buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error);
@@ -313,16 +345,16 @@ g_part_bsd_read(struct g_part_table *bas
table = (struct g_part_bsd_table *)basetable;
msize = pp->mediasize / pp->sectorsize;
- buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error);
- if (buf == NULL)
+ table->bbarea = g_read_data(cp, 0, BBSIZE, &error);
+ if (table->bbarea == NULL)
return (error);
- table->label = buf;
+ buf = table->bbarea + pp->sectorsize;
if (le32dec(buf + 40) != pp->sectorsize)
goto invalid_label;
sectors = le32dec(buf + 44);
- if (sectors < 1 || sectors > 63)
+ if (sectors < 1 || sectors > 255)
goto invalid_label;
if (sectors != basetable->gpt_sectors && !basetable->gpt_fixgeom) {
g_part_geometry_heads(msize, sectors, &chs, &heads);
@@ -341,8 +373,13 @@ g_part_bsd_read(struct g_part_table *bas
printf("GEOM: %s: geometry does not match label.\n", pp->name);
chs = le32dec(buf + 60);
- if (chs < 1 || chs > msize)
+ if (chs < 1)
goto invalid_label;
+ /* Fix-up a sysinstall bug. */
+ if (chs > msize) {
+ chs = msize;
+ le32enc(buf + 60, msize);
+ }
if (chs != msize)
printf("GEOM: %s: media size does not match label.\n",
pp->name);
@@ -367,8 +404,6 @@ g_part_bsd_read(struct g_part_table *bas
part.p_cpg = le16dec(p + 14);
if (part.p_size == 0)
continue;
- if (part.p_fstype == FS_UNUSED && index != RAW_PART)
- continue;
if (part.p_offset < table->offset)
continue;
baseentry = g_part_new_entry(basetable, index + 1,
@@ -376,7 +411,7 @@ g_part_bsd_read(struct g_part_table *bas
part.p_offset - table->offset + part.p_size - 1);
entry = (struct g_part_bsd_entry *)baseentry;
entry->part = part;
- if (part.p_fstype == FS_UNUSED)
+ if (index == RAW_PART)
baseentry->gpe_internal = 1;
}
@@ -384,7 +419,7 @@ g_part_bsd_read(struct g_part_table *bas
invalid_label:
printf("GEOM: %s: invalid disklabel.\n", pp->name);
- g_free(table->label);
+ g_free(table->bbarea);
return (EINVAL);
}
@@ -417,14 +452,15 @@ g_part_bsd_write(struct g_part_table *ba
struct g_part_bsd_entry *entry;
struct g_part_bsd_table *table;
uint16_t sum;
- u_char *p, *pe;
+ u_char *label, *p, *pe;
int error, index;
pp = cp->provider;
table = (struct g_part_bsd_table *)basetable;
baseentry = LIST_FIRST(&basetable->gpt_entry);
+ label = table->bbarea + pp->sectorsize;
for (index = 1; index <= basetable->gpt_entries; index++) {
- p = table->label + 148 + (index - 1) * 16;
+ p = label + 148 + (index - 1) * 16;
entry = (baseentry != NULL && index == baseentry->gpe_index)
? (struct g_part_bsd_entry *)baseentry : NULL;
if (entry != NULL && !baseentry->gpe_deleted) {
@@ -442,13 +478,13 @@ g_part_bsd_write(struct g_part_table *ba
}
/* Calculate checksum. */
- le16enc(table->label + 136, 0);
- pe = table->label + 148 + basetable->gpt_entries * 16;
+ le16enc(label + 136, 0);
+ pe = label + 148 + basetable->gpt_entries * 16;
sum = 0;
- for (p = table->label; p < pe; p += 2)
+ for (p = label; p < pe; p += 2)
sum ^= le16dec(p);
- le16enc(table->label + 136, sum);
+ le16enc(label + 136, sum);
- error = g_write_data(cp, pp->sectorsize, table->label, pp->sectorsize);
+ error = g_write_data(cp, 0, table->bbarea, BBSIZE);
return (error);
}
Copied and modified: stable/7/sys/geom/part/g_part_ebr.c (from r188354, head/sys/geom/part/g_part_ebr.c)
==============================================================================
--- head/sys/geom/part/g_part_ebr.c Sun Feb 8 23:51:44 2009 (r188354, copy source)
+++ stable/7/sys/geom/part/g_part_ebr.c Tue Mar 17 19:38:40 2009 (r189935)
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/sbuf.h>
-#include <sys/syscallsubr.h>
#include <sys/systm.h>
#include <geom/geom.h>
#include <geom/part/g_part.h>
@@ -55,12 +54,15 @@ struct g_part_ebr_table {
struct g_part_ebr_entry {
struct g_part_entry base;
struct dos_partition ent;
+ int alias;
};
static int g_part_ebr_add(struct g_part_table *, struct g_part_entry *,
struct g_part_parms *);
static int g_part_ebr_create(struct g_part_table *, struct g_part_parms *);
static int g_part_ebr_destroy(struct g_part_table *, struct g_part_parms *);
+static int g_part_ebr_devalias(struct g_part_table *, struct g_part_entry *,
+ char *, size_t);
static void g_part_ebr_dumpconf(struct g_part_table *, struct g_part_entry *,
struct sbuf *, const char *);
static int g_part_ebr_dumpto(struct g_part_table *, struct g_part_entry *);
@@ -68,6 +70,8 @@ static int g_part_ebr_modify(struct g_pa
struct g_part_parms *);
static const char *g_part_ebr_name(struct g_part_table *, struct g_part_entry *,
char *, size_t);
+static int g_part_ebr_precheck(struct g_part_table *, enum g_part_ctl,
+ struct g_part_parms *);
static int g_part_ebr_probe(struct g_part_table *, struct g_consumer *);
static int g_part_ebr_read(struct g_part_table *, struct g_consumer *);
static int g_part_ebr_setunset(struct g_part_table *, struct g_part_entry *,
@@ -80,10 +84,12 @@ static kobj_method_t g_part_ebr_methods[
KOBJMETHOD(g_part_add, g_part_ebr_add),
KOBJMETHOD(g_part_create, g_part_ebr_create),
KOBJMETHOD(g_part_destroy, g_part_ebr_destroy),
+ KOBJMETHOD(g_part_devalias, g_part_ebr_devalias),
KOBJMETHOD(g_part_dumpconf, g_part_ebr_dumpconf),
KOBJMETHOD(g_part_dumpto, g_part_ebr_dumpto),
KOBJMETHOD(g_part_modify, g_part_ebr_modify),
KOBJMETHOD(g_part_name, g_part_ebr_name),
+ KOBJMETHOD(g_part_precheck, g_part_ebr_precheck),
KOBJMETHOD(g_part_probe, g_part_ebr_probe),
KOBJMETHOD(g_part_read, g_part_ebr_read),
KOBJMETHOD(g_part_setunset, g_part_ebr_setunset),
@@ -102,6 +108,9 @@ static struct g_part_scheme g_part_ebr_s
};
G_PART_SCHEME_DECLARE(g_part_ebr);
+static void ebr_set_chs(struct g_part_table *, uint32_t, u_char *, u_char *,
+ u_char *);
+
static void
ebr_entry_decode(const char *p, struct dos_partition *ent)
{
@@ -117,19 +126,142 @@ ebr_entry_decode(const char *p, struct d
ent->dp_size = le32dec(p + 12);
}
+static void
+ebr_entry_link(struct g_part_table *table, uint32_t start, uint32_t end,
+ u_char *buf)
+{
+
+ buf[0] = 0 /* dp_flag */;
+ ebr_set_chs(table, start, &buf[3] /* dp_scyl */, &buf[1] /* dp_shd */,
+ &buf[2] /* dp_ssect */);
+ buf[4] = 5 /* dp_typ */;
+ ebr_set_chs(table, end, &buf[7] /* dp_ecyl */, &buf[5] /* dp_ehd */,
+ &buf[6] /* dp_esect */);
+ le32enc(buf + 8, start);
+ le32enc(buf + 12, end - start + 1);
+}
+
+static int
+ebr_parse_type(const char *type, u_char *dp_typ)
+{
+ const char *alias;
+ char *endp;
+ long lt;
+
+ if (type[0] == '!') {
+ lt = strtol(type + 1, &endp, 0);
+ if (type[1] == '\0' || *endp != '\0' || lt <= 0 || lt >= 256)
+ return (EINVAL);
+ *dp_typ = (u_char)lt;
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
+ if (!strcasecmp(type, alias)) {
+ *dp_typ = DOSPTYP_386BSD;
+ return (0);
+ }
+ return (EINVAL);
+}
+
+static void
+ebr_set_chs(struct g_part_table *table, uint32_t lba, u_char *cylp, u_char *hdp,
+ u_char *secp)
+{
+ uint32_t cyl, hd, sec;
+
+ sec = lba % table->gpt_sectors + 1;
+ lba /= table->gpt_sectors;
+ hd = lba % table->gpt_heads;
+ lba /= table->gpt_heads;
+ cyl = lba;
+ if (cyl > 1023)
+ sec = hd = cyl = ~0;
+
+ *cylp = cyl & 0xff;
+ *hdp = hd & 0xff;
+ *secp = (sec & 0x3f) | ((cyl >> 2) & 0xc0);
+}
+
static int
g_part_ebr_add(struct g_part_table *basetable, struct g_part_entry *baseentry,
struct g_part_parms *gpp)
{
+ struct g_geom *gp;
+ struct g_provider *pp;
+ struct g_part_ebr_entry *entry;
+ uint32_t start, size, sectors;
- return (ENOSYS);
+ if (gpp->gpp_parms & G_PART_PARM_LABEL)
+ return (EINVAL);
+
+ gp = basetable->gpt_gp;
+ pp = LIST_FIRST(&gp->consumer)->provider;
+ sectors = basetable->gpt_sectors;
+
+ entry = (struct g_part_ebr_entry *)baseentry;
+
+ start = gpp->gpp_start;
+ size = gpp->gpp_size;
+ if (size < 2 * sectors)
+ return (EINVAL);
+ if (start % sectors) {
+ size = size - sectors + (start % sectors);
+ start = start - (start % sectors) + sectors;
+ }
+ if (size % sectors)
+ size = size - (size % sectors);
+ if (size < 2 * sectors)
+ return (EINVAL);
+
+ if (baseentry->gpe_deleted)
+ bzero(&entry->ent, sizeof(entry->ent));
+
+ KASSERT(baseentry->gpe_start <= start, (__func__));
+ KASSERT(baseentry->gpe_end >= start + size - 1, (__func__));
+ baseentry->gpe_index = (start / sectors) + 1;
+ baseentry->gpe_offset = (off_t)(start + sectors) * pp->sectorsize;
+ baseentry->gpe_start = start;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable
mailing list