svn commit: r209497 - in stable/8: sbin/geom/class/part sys/geom/part

Andrey V. Elsukov ae at FreeBSD.org
Thu Jun 24 05:52:45 UTC 2010


Author: ae
Date: Thu Jun 24 05:52:44 2010
New Revision: 209497
URL: http://svn.freebsd.org/changeset/base/209497

Log:
  MFC r207094 (by marcel):
  Implement the resize verb and add support for resizing partitions
  for all schemes but EBR.
  
  MFC r207095 (by marcel):
  Implement the resize command for resizing partitions. Without new
  size, the partition in question is resized to fill all available
  space.
  
  Approved by:	kib (mentor)

Modified:
  stable/8/sbin/geom/class/part/geom_part.c
  stable/8/sbin/geom/class/part/gpart.8
  stable/8/sys/geom/part/g_part.c
  stable/8/sys/geom/part/g_part_apm.c
  stable/8/sys/geom/part/g_part_bsd.c
  stable/8/sys/geom/part/g_part_gpt.c
  stable/8/sys/geom/part/g_part_if.m
  stable/8/sys/geom/part/g_part_mbr.c
  stable/8/sys/geom/part/g_part_pc98.c
  stable/8/sys/geom/part/g_part_vtoc8.c
Directory Properties:
  stable/8/sbin/geom/   (props changed)
  stable/8/sbin/geom/class/part/   (props changed)
  stable/8/sbin/geom/class/stripe/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sbin/geom/class/part/geom_part.c
==============================================================================
--- stable/8/sbin/geom/class/part/geom_part.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sbin/geom/class/part/geom_part.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -147,6 +147,13 @@ struct g_command PUBSYM(class_commands)[
 		G_OPT_SENTINEL },
 	  "geom", NULL
 	},
+	{ "resize", 0, gpart_issue, {
+		{ 's', "size", autofill, G_TYPE_ASCLBA },
+		{ 'i', index_param, NULL, G_TYPE_ASCNUM },
+		{ 'f', "flags", flags, G_TYPE_STRING },
+		G_OPT_SENTINEL },
+	  "geom", NULL
+	},
 	G_CMD_SENTINEL
 };
 
@@ -257,6 +264,99 @@ fmtattrib(struct gprovider *pp)
 }
 
 static int
+gpart_autofill_resize(struct gctl_req *req)
+{
+	struct gmesh mesh;
+	struct gclass *cp;
+	struct ggeom *gp;
+	struct gprovider *pp;
+	unsigned long long last, size, start, new_size;
+	unsigned long long lba, new_lba;
+	const char *s;
+	char *val;
+	int error, idx;
+
+	s = gctl_get_ascii(req, "size");
+	if (*s == '*')
+		new_size = (unsigned long long)atoll(s);
+	else
+		return (0);
+
+	s = gctl_get_ascii(req, index_param);
+	idx = strtol(s, &val, 10);
+	if (idx < 1 || *s == '\0' || *val != '\0')
+		errx(EXIT_FAILURE, "invalid partition index");
+
+	error = geom_gettree(&mesh);
+	if (error)
+		return (error);
+	s = gctl_get_ascii(req, "class");
+	if (s == NULL)
+		abort();
+	cp = find_class(&mesh, s);
+	if (cp == NULL)
+		errx(EXIT_FAILURE, "Class %s not found.", s);
+	s = gctl_get_ascii(req, "geom");
+	if (s == NULL)
+		abort();
+	gp = find_geom(cp, s);
+	if (gp == NULL)
+		errx(EXIT_FAILURE, "No such geom: %s.", s);
+	last = atoll(find_geomcfg(gp, "last"));
+
+	LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+		s = find_provcfg(pp, "index");
+		if (s == NULL)
+			continue;
+		if (atoi(s) == idx)
+			break;
+	}
+	if (pp == NULL)
+		errx(EXIT_FAILURE, "invalid partition index");
+
+	s = find_provcfg(pp, "start");
+	if (s == NULL) {
+		s = find_provcfg(pp, "offset");
+		start = atoll(s) / pp->lg_sectorsize;
+	} else
+		start = atoll(s);
+	s = find_provcfg(pp, "end");
+	if (s == NULL) {
+		s = find_provcfg(pp, "length");
+		lba = start + atoll(s) / pp->lg_sectorsize;
+	} else
+		lba = atoll(s) + 1;
+
+	if (lba > last)
+		return (ENOSPC);
+	size = lba - start;
+	pp = find_provider(gp, lba);
+	if (pp == NULL)
+		new_size = last - start + 1;
+	else {
+		s = find_provcfg(pp, "start");
+		if (s == NULL) {
+			s = find_provcfg(pp, "offset");
+			new_lba = atoll(s) / pp->lg_sectorsize;
+		} else
+			new_lba = atoll(s);
+		/* Is there any free space between current and
+		 * next providers?
+		 */
+		if (new_lba > lba)
+			new_size = new_lba - start;
+		else
+			return (ENOSPC);
+	}
+	asprintf(&val, "%llu", new_size);
+	if (val == NULL)
+		return (ENOMEM);
+	gctl_change_param(req, "size", -1, val);
+
+	return (0);
+}
+
+static int
 gpart_autofill(struct gctl_req *req)
 {
 	struct gmesh mesh;
@@ -271,6 +371,8 @@ gpart_autofill(struct gctl_req *req)
 	int error, has_size, has_start;
 
 	s = gctl_get_ascii(req, "verb");
+	if (strcmp(s, "resize") == 0)
+		return gpart_autofill_resize(req);
 	if (strcmp(s, "add") != 0)
 		return (0);
 

Modified: stable/8/sbin/geom/class/part/gpart.8
==============================================================================
--- stable/8/sbin/geom/class/part/gpart.8	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sbin/geom/class/part/gpart.8	Thu Jun 24 05:52:44 2010	(r209497)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 22, 2010
+.Dd June 24, 2010
 .Dt GPART 8
 .Os
 .Sh NAME
@@ -123,6 +123,13 @@ utility:
 .Op Fl t Ar type
 .Op Fl f Ar flags
 .Ar geom
+.\" ==== RESIZE ====
+.Nm
+.Cm resize
+.Fl i Ar index
+.Op Fl s Ar size
+.Op Fl f Ar flags
+.Ar geom
 .\" ==== SET ====
 .Nm
 .Cm set
@@ -334,6 +341,32 @@ See the section entitled
 below for a discussion
 about its use.
 .El
+.\" ==== RESIZE ====
+.It Cm resize
+Resize a partition from geom
+.Ar geom
+and further identified by the
+.Fl i Ar index
+option.
+New partition size is expressed in logical block
+numbers and can be given by the 
+.Fl s Ar size
+option.
+If
+.Fl s
+option is ommited then new size is automatically calculated
+to maximum available from given geom
+.Ar geom .
+.Pp
+Additional options include:
+.Bl -tag -width 10n
+.It Fl f Ar flags
+Additional operational flags.
+See the section entitled
+.Sx "OPERATIONAL FLAGS"
+below for a discussion
+about its use.
+.El
 .\" ==== SET ====
 .It Cm set
 Set the named attribute on the partition entry.
@@ -450,7 +483,7 @@ The scheme-specific types are
 .Qq Li "!FreeBSD-ZFS"
 for APM,
 .Qq Li "!516e7cba-6ecf-11d6-8ff8-00022d09712b"
- for GPT, and 0x0904 for VTOC8.
+for GPT, and 0x0904 for VTOC8.
 .It Cm mbr
 A partition that is sub-partitioned by a master boot record (MBR).
 This type is known as

Modified: stable/8/sys/geom/part/g_part.c
==============================================================================
--- stable/8/sys/geom/part/g_part.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -968,9 +968,85 @@ g_part_ctl_recover(struct gctl_req *req,
 static int
 g_part_ctl_resize(struct gctl_req *req, struct g_part_parms *gpp)
 {
-	gctl_error(req, "%d verb 'resize'", ENOSYS);
-	return (ENOSYS);
-} 
+	struct g_geom *gp;
+	struct g_provider *pp;
+	struct g_part_entry *pe, *entry;
+	struct g_part_table *table;
+	struct sbuf *sb;
+	quad_t end;
+	int error;
+
+	gp = gpp->gpp_geom;
+	G_PART_TRACE((G_T_TOPOLOGY, "%s(%s)", __func__, gp->name));
+	g_topology_assert();
+	table = gp->softc;
+
+	/* check gpp_index */
+	LIST_FOREACH(entry, &table->gpt_entry, gpe_entry) {
+		if (entry->gpe_deleted || entry->gpe_internal)
+			continue;
+		if (entry->gpe_index == gpp->gpp_index)
+			break;
+	}
+	if (entry == NULL) {
+		gctl_error(req, "%d index '%d'", ENOENT, gpp->gpp_index);
+		return (ENOENT);
+	}
+
+	/* check gpp_size */
+	end = entry->gpe_start + gpp->gpp_size - 1;
+	if (gpp->gpp_size < 1 || end > table->gpt_last) {
+		gctl_error(req, "%d size '%jd'", EINVAL,
+		    (intmax_t)gpp->gpp_size);
+		return (EINVAL);
+	}
+
+	LIST_FOREACH(pe, &table->gpt_entry, gpe_entry) {
+		if (pe->gpe_deleted || pe->gpe_internal || pe == entry)
+			continue;
+		if (end >= pe->gpe_start && end <= pe->gpe_end) {
+			gctl_error(req, "%d end '%jd'", ENOSPC,
+			    (intmax_t)end);
+			return (ENOSPC);
+		}
+		if (entry->gpe_start < pe->gpe_start && end > pe->gpe_end) {
+			gctl_error(req, "%d size '%jd'", ENOSPC,
+			    (intmax_t)gpp->gpp_size);
+			return (ENOSPC);
+		}
+	}
+
+	pp = entry->gpe_pp;
+	if ((g_debugflags & 16) == 0 &&
+	    (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)) {
+		gctl_error(req, "%d", EBUSY);
+		return (EBUSY);
+	}
+
+	error = G_PART_RESIZE(table, entry, gpp);
+	if (error) {
+		gctl_error(req, "%d", error);
+		return (error);
+	}
+
+	if (!entry->gpe_created)
+		entry->gpe_modified = 1;
+
+	/* update mediasize of changed provider */
+	pp->mediasize = (entry->gpe_end - entry->gpe_start + 1) *
+		pp->sectorsize;
+
+	/* Provide feedback if so requested. */
+	if (gpp->gpp_parms & G_PART_PARM_OUTPUT) {
+		sb = sbuf_new_auto();
+		G_PART_FULLNAME(table, entry, sb, gp->name);
+		sbuf_cat(sb, " resized\n");
+		sbuf_finish(sb);
+		gctl_set_param(req, "output", sbuf_data(sb), sbuf_len(sb) + 1);
+		sbuf_delete(sb);
+	}
+	return (0);
+}
 
 static int
 g_part_ctl_setunset(struct gctl_req *req, struct g_part_parms *gpp,
@@ -1206,7 +1282,8 @@ g_part_ctlreq(struct gctl_req *req, stru
 			mparms |= G_PART_PARM_GEOM;
 		} else if (!strcmp(verb, "resize")) {
 			ctlreq = G_PART_CTL_RESIZE;
-			mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
+			mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX |
+			    G_PART_PARM_SIZE;
 		}
 		break;
 	case 's':

Modified: stable/8/sys/geom/part/g_part_apm.c
==============================================================================
--- stable/8/sys/geom/part/g_part_apm.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part_apm.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -74,6 +74,8 @@ static int g_part_apm_read(struct g_part
 static const char *g_part_apm_type(struct g_part_table *, struct g_part_entry *,
     char *, size_t);
 static int g_part_apm_write(struct g_part_table *, struct g_consumer *);
+static int g_part_apm_resize(struct g_part_table *, struct g_part_entry *,
+    struct g_part_parms *);
 
 static kobj_method_t g_part_apm_methods[] = {
 	KOBJMETHOD(g_part_add,		g_part_apm_add),
@@ -82,6 +84,7 @@ static kobj_method_t g_part_apm_methods[
 	KOBJMETHOD(g_part_dumpconf,	g_part_apm_dumpconf),
 	KOBJMETHOD(g_part_dumpto,	g_part_apm_dumpto),
 	KOBJMETHOD(g_part_modify,	g_part_apm_modify),
+	KOBJMETHOD(g_part_resize,	g_part_apm_resize),
 	KOBJMETHOD(g_part_name,		g_part_apm_name),
 	KOBJMETHOD(g_part_probe,	g_part_apm_probe),
 	KOBJMETHOD(g_part_read,		g_part_apm_read),
@@ -338,6 +341,19 @@ g_part_apm_modify(struct g_part_table *b
 	return (0);
 }
 
+static int
+g_part_apm_resize(struct g_part_table *basetable,
+    struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+	struct g_part_apm_entry *entry;
+
+	entry = (struct g_part_apm_entry *)baseentry;
+	baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
+	entry->ent.ent_size = gpp->gpp_size;
+
+	return (0);
+}
+
 static const char *
 g_part_apm_name(struct g_part_table *table, struct g_part_entry *baseentry,
     char *buf, size_t bufsz)

Modified: stable/8/sys/geom/part/g_part_bsd.c
==============================================================================
--- stable/8/sys/geom/part/g_part_bsd.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part_bsd.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -73,6 +73,8 @@ static int g_part_bsd_read(struct g_part
 static const char *g_part_bsd_type(struct g_part_table *, struct g_part_entry *,
     char *, size_t);
 static int g_part_bsd_write(struct g_part_table *, struct g_consumer *);
+static int g_part_bsd_resize(struct g_part_table *, struct g_part_entry *,
+    struct g_part_parms *);
 
 static kobj_method_t g_part_bsd_methods[] = {
 	KOBJMETHOD(g_part_add,		g_part_bsd_add),
@@ -82,6 +84,7 @@ static kobj_method_t g_part_bsd_methods[
 	KOBJMETHOD(g_part_dumpconf,	g_part_bsd_dumpconf),
 	KOBJMETHOD(g_part_dumpto,	g_part_bsd_dumpto),
 	KOBJMETHOD(g_part_modify,	g_part_bsd_modify),
+	KOBJMETHOD(g_part_resize,	g_part_bsd_resize),
 	KOBJMETHOD(g_part_name,		g_part_bsd_name),
 	KOBJMETHOD(g_part_probe,	g_part_bsd_probe),
 	KOBJMETHOD(g_part_read,		g_part_bsd_read),
@@ -296,6 +299,19 @@ g_part_bsd_modify(struct g_part_table *b
 	return (0);
 }
 
+static int
+g_part_bsd_resize(struct g_part_table *basetable,
+    struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+	struct g_part_bsd_entry *entry;
+
+	entry = (struct g_part_bsd_entry *)baseentry;
+	baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
+	entry->part.p_size = gpp->gpp_size;
+
+	return (0);
+}
+
 static const char *
 g_part_bsd_name(struct g_part_table *table, struct g_part_entry *baseentry,
     char *buf, size_t bufsz)

Modified: stable/8/sys/geom/part/g_part_gpt.c
==============================================================================
--- stable/8/sys/geom/part/g_part_gpt.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part_gpt.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -103,6 +103,8 @@ static int g_part_gpt_read(struct g_part
 static const char *g_part_gpt_type(struct g_part_table *, struct g_part_entry *,
     char *, size_t);
 static int g_part_gpt_write(struct g_part_table *, struct g_consumer *);
+static int g_part_gpt_resize(struct g_part_table *, struct g_part_entry *,
+    struct g_part_parms *);
 
 static kobj_method_t g_part_gpt_methods[] = {
 	KOBJMETHOD(g_part_add,		g_part_gpt_add),
@@ -112,6 +114,7 @@ static kobj_method_t g_part_gpt_methods[
 	KOBJMETHOD(g_part_dumpconf,	g_part_gpt_dumpconf),
 	KOBJMETHOD(g_part_dumpto,	g_part_gpt_dumpto),
 	KOBJMETHOD(g_part_modify,	g_part_gpt_modify),
+	KOBJMETHOD(g_part_resize,	g_part_gpt_resize),
 	KOBJMETHOD(g_part_name,		g_part_gpt_name),
 	KOBJMETHOD(g_part_probe,	g_part_gpt_probe),
 	KOBJMETHOD(g_part_read,		g_part_gpt_read),
@@ -532,6 +535,19 @@ g_part_gpt_modify(struct g_part_table *b
 	return (0);
 }
 
+static int
+g_part_gpt_resize(struct g_part_table *basetable,
+    struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+	struct g_part_gpt_entry *entry;
+	entry = (struct g_part_gpt_entry *)baseentry;
+
+	baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
+	entry->ent.ent_lba_end = baseentry->gpe_end;
+
+	return (0);
+}
+
 static const char *
 g_part_gpt_name(struct g_part_table *table, struct g_part_entry *baseentry,
     char *buf, size_t bufsz)

Modified: stable/8/sys/geom/part/g_part_if.m
==============================================================================
--- stable/8/sys/geom/part/g_part_if.m	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part_if.m	Thu Jun 24 05:52:44 2010	(r209497)
@@ -58,6 +58,13 @@ CODE {
 	{
 		return (0);
 	}
+
+	static int
+	default_resize(struct g_part_table *t __unused,
+	    struct g_part_entry *e __unused, struct g_part_parms *p __unused)
+	{
+		return (ENOSYS);
+	}
 };
 
 # add() - scheme specific processing for the add verb.
@@ -114,6 +121,13 @@ METHOD int modify {
 	struct g_part_parms *gpp;
 };
 
+# resize() - scheme specific processing for the resize verb.
+METHOD int resize {
+	struct g_part_table *table;
+	struct g_part_entry *entry;
+	struct g_part_parms *gpp;
+} DEFAULT default_resize;
+
 # name() - return the name of the given partition entry.
 # Typical names are "p1", "s0" or "c".
 METHOD const char * name {

Modified: stable/8/sys/geom/part/g_part_mbr.c
==============================================================================
--- stable/8/sys/geom/part/g_part_mbr.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part_mbr.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -76,6 +76,8 @@ static int g_part_mbr_setunset(struct g_
 static const char *g_part_mbr_type(struct g_part_table *, struct g_part_entry *,
     char *, size_t);
 static int g_part_mbr_write(struct g_part_table *, struct g_consumer *);
+static int g_part_mbr_resize(struct g_part_table *, struct g_part_entry *,
+    struct g_part_parms *);
 
 static kobj_method_t g_part_mbr_methods[] = {
 	KOBJMETHOD(g_part_add,		g_part_mbr_add),
@@ -85,6 +87,7 @@ static kobj_method_t g_part_mbr_methods[
 	KOBJMETHOD(g_part_dumpconf,	g_part_mbr_dumpconf),
 	KOBJMETHOD(g_part_dumpto,	g_part_mbr_dumpto),
 	KOBJMETHOD(g_part_modify,	g_part_mbr_modify),
+	KOBJMETHOD(g_part_resize,	g_part_mbr_resize),
 	KOBJMETHOD(g_part_name,		g_part_mbr_name),
 	KOBJMETHOD(g_part_probe,	g_part_mbr_probe),
 	KOBJMETHOD(g_part_read,		g_part_mbr_read),
@@ -302,6 +305,31 @@ g_part_mbr_modify(struct g_part_table *b
 	return (0);
 }
 
+static int
+g_part_mbr_resize(struct g_part_table *basetable,
+    struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+	struct g_part_mbr_entry *entry;
+	uint32_t size, sectors;
+
+	sectors = basetable->gpt_sectors;
+	size = gpp->gpp_size;
+
+	if (size < sectors)
+		return (EINVAL);
+	if (size % sectors)
+		size = size - (size % sectors);
+	if (size < sectors)
+		return (EINVAL);
+
+	entry = (struct g_part_mbr_entry *)baseentry;
+	baseentry->gpe_end = baseentry->gpe_start + size - 1;
+	entry->ent.dp_size = size;
+	mbr_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
+	    &entry->ent.dp_ehd, &entry->ent.dp_esect);
+	return (0);
+}
+
 static const char *
 g_part_mbr_name(struct g_part_table *table, struct g_part_entry *baseentry,
     char *buf, size_t bufsz)

Modified: stable/8/sys/geom/part/g_part_pc98.c
==============================================================================
--- stable/8/sys/geom/part/g_part_pc98.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part_pc98.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -77,6 +77,8 @@ static int g_part_pc98_setunset(struct g
 static const char *g_part_pc98_type(struct g_part_table *,
     struct g_part_entry *, char *, size_t);
 static int g_part_pc98_write(struct g_part_table *, struct g_consumer *);
+static int g_part_pc98_resize(struct g_part_table *, struct g_part_entry *,  
+    struct g_part_parms *);
 
 static kobj_method_t g_part_pc98_methods[] = {
 	KOBJMETHOD(g_part_add,		g_part_pc98_add),
@@ -86,6 +88,7 @@ static kobj_method_t g_part_pc98_methods
 	KOBJMETHOD(g_part_dumpconf,	g_part_pc98_dumpconf),
 	KOBJMETHOD(g_part_dumpto,	g_part_pc98_dumpto),
 	KOBJMETHOD(g_part_modify,	g_part_pc98_modify),
+	KOBJMETHOD(g_part_resize,	g_part_pc98_resize),
 	KOBJMETHOD(g_part_name,		g_part_pc98_name),
 	KOBJMETHOD(g_part_probe,	g_part_pc98_probe),
 	KOBJMETHOD(g_part_read,		g_part_pc98_read),
@@ -308,6 +311,31 @@ g_part_pc98_modify(struct g_part_table *
 	return (0);
 }
 
+static int
+g_part_pc98_resize(struct g_part_table *basetable,
+    struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+	struct g_part_pc98_entry *entry;
+	uint32_t size, cyl;
+
+	cyl = basetable->gpt_heads * basetable->gpt_sectors;
+	size = gpp->gpp_size;
+
+	if (size < cyl)
+		return (EINVAL);
+	if (size % cyl)
+		size = size - (size % cyl);
+	if (size < cyl)
+		return (EINVAL);
+
+	entry = (struct g_part_pc98_entry *)baseentry;
+	baseentry->gpe_end = baseentry->gpe_start + size - 1;
+	pc98_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
+	    &entry->ent.dp_ehd, &entry->ent.dp_esect);
+
+	return (0);
+}
+
 static const char *
 g_part_pc98_name(struct g_part_table *table, struct g_part_entry *baseentry,
     char *buf, size_t bufsz)

Modified: stable/8/sys/geom/part/g_part_vtoc8.c
==============================================================================
--- stable/8/sys/geom/part/g_part_vtoc8.c	Thu Jun 24 05:49:58 2010	(r209496)
+++ stable/8/sys/geom/part/g_part_vtoc8.c	Thu Jun 24 05:52:44 2010	(r209497)
@@ -67,6 +67,8 @@ static int g_part_vtoc8_read(struct g_pa
 static const char *g_part_vtoc8_type(struct g_part_table *, struct g_part_entry *,
     char *, size_t);
 static int g_part_vtoc8_write(struct g_part_table *, struct g_consumer *);
+static int g_part_vtoc8_resize(struct g_part_table *, struct g_part_entry *,  
+    struct g_part_parms *);
 
 static kobj_method_t g_part_vtoc8_methods[] = {
 	KOBJMETHOD(g_part_add,		g_part_vtoc8_add),
@@ -75,6 +77,7 @@ static kobj_method_t g_part_vtoc8_method
 	KOBJMETHOD(g_part_dumpconf,	g_part_vtoc8_dumpconf),
 	KOBJMETHOD(g_part_dumpto,	g_part_vtoc8_dumpto),
 	KOBJMETHOD(g_part_modify,	g_part_vtoc8_modify),
+	KOBJMETHOD(g_part_resize,	g_part_vtoc8_resize),
 	KOBJMETHOD(g_part_name,		g_part_vtoc8_name),
 	KOBJMETHOD(g_part_probe,	g_part_vtoc8_probe),
 	KOBJMETHOD(g_part_read,		g_part_vtoc8_read),
@@ -296,6 +299,26 @@ g_part_vtoc8_modify(struct g_part_table 
 	return (0);
 }
 
+static int
+g_part_vtoc8_resize(struct g_part_table *basetable,
+    struct g_part_entry *entry, struct g_part_parms *gpp)
+{
+	struct g_part_vtoc8_table *table;
+	uint64_t size;
+
+	table = (struct g_part_vtoc8_table *)basetable;
+	size = gpp->gpp_size;
+	if (size % table->secpercyl)
+		size = size - (size % table->secpercyl);
+	if (size < table->secpercyl)
+		return (EINVAL);
+
+	entry->gpe_end = entry->gpe_start + size - 1;
+	be32enc(&table->vtoc.map[entry->gpe_index - 1].nblks, size);
+
+	return (0);
+}
+
 static const char *
 g_part_vtoc8_name(struct g_part_table *table, struct g_part_entry *baseentry,
     char *buf, size_t bufsz)


More information about the svn-src-all mailing list