Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 May 2014 12:04:45 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r265912 - stable/10/sys/geom/part
Message-ID:  <201405121204.s4CC4j39099322@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Mon May 12 12:04:44 2014
New Revision: 265912
URL: http://svnweb.freebsd.org/changeset/base/265912

Log:
  MFC r256690:
    Add an automatic resize support to the GEOM_PART class.
  
    When parent provider has been resized, the scheme specific G_PART_RESIZE
    method does an update of scheme's metadata. But all changes are not saved
    to disk, until `gpart commit` will be called.
  
  MFC r265336:
    Add an advice what to do when partition was automatically resized.

Modified:
  stable/10/sys/geom/part/g_part.c
  stable/10/sys/geom/part/g_part_apm.c
  stable/10/sys/geom/part/g_part_bsd.c
  stable/10/sys/geom/part/g_part_ebr.c
  stable/10/sys/geom/part/g_part_gpt.c
  stable/10/sys/geom/part/g_part_mbr.c
  stable/10/sys/geom/part/g_part_pc98.c
  stable/10/sys/geom/part/g_part_vtoc8.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/geom/part/g_part.c
==============================================================================
--- stable/10/sys/geom/part/g_part.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part.c	Mon May 12 12:04:44 2014	(r265912)
@@ -133,6 +133,7 @@ static g_dumpconf_t g_part_dumpconf;
 static g_orphan_t g_part_orphan;
 static g_spoiled_t g_part_spoiled;
 static g_start_t g_part_start;
+static g_resize_t g_part_resize;
 
 static struct g_class g_part_class = {
 	.name = "PART",
@@ -149,6 +150,7 @@ static struct g_class g_part_class = {
 	.orphan = g_part_orphan,
 	.spoiled = g_part_spoiled,
 	.start = g_part_start,
+	.resize = g_part_resize
 };
 
 DECLARE_GEOM_CLASS(g_part_class, g_part);
@@ -2049,6 +2051,32 @@ g_part_dumpconf(struct sbuf *sb, const c
 }
 
 static void
+g_part_resize(struct g_consumer *cp)
+{
+	struct g_part_table *table;
+
+	G_PART_TRACE((G_T_TOPOLOGY, "%s(%s)", __func__, cp->provider->name));
+	g_topology_assert();
+
+	table = cp->geom->softc;
+	if (table->gpt_opened == 0) {
+		if (g_access(cp, 1, 1, 1) != 0)
+			return;
+		table->gpt_opened = 1;
+	}
+	if (G_PART_RESIZE(table, NULL, NULL) == 0)
+		printf("GEOM_PART: %s was automatically resized.\n"
+		    "  Use `gpart commit %s` to save changes or "
+		    "`gpart undo %s` to revert them.\n", cp->geom->name,
+		    cp->geom->name, cp->geom->name);
+	if (g_part_check_integrity(table, cp) != 0) {
+		g_access(cp, -1, -1, -1);
+		table->gpt_opened = 0;
+		g_part_wither(table->gpt_gp, ENXIO);
+	}
+}
+
+static void
 g_part_orphan(struct g_consumer *cp)
 {
 	struct g_provider *pp;

Modified: stable/10/sys/geom/part/g_part_apm.c
==============================================================================
--- stable/10/sys/geom/part/g_part_apm.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part_apm.c	Mon May 12 12:04:44 2014	(r265912)
@@ -359,6 +359,14 @@ g_part_apm_resize(struct g_part_table *b
     struct g_part_entry *baseentry, struct g_part_parms *gpp)
 {
 	struct g_part_apm_entry *entry;
+	struct g_provider *pp;
+
+	if (baseentry == NULL) {
+		pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
+		basetable->gpt_last = MIN(pp->mediasize / pp->sectorsize,
+		    UINT32_MAX) - 1;
+		return (0);
+	}
 
 	entry = (struct g_part_apm_entry *)baseentry;
 	baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;

Modified: stable/10/sys/geom/part/g_part_bsd.c
==============================================================================
--- stable/10/sys/geom/part/g_part_bsd.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part_bsd.c	Mon May 12 12:04:44 2014	(r265912)
@@ -304,12 +304,40 @@ g_part_bsd_modify(struct g_part_table *b
 	return (0);
 }
 
+static void
+bsd_set_rawsize(struct g_part_table *basetable, struct g_provider *pp)
+{
+	struct g_part_bsd_table *table;
+	struct g_part_bsd_entry *entry;
+	struct g_part_entry *baseentry;
+	uint32_t msize;
+
+	table = (struct g_part_bsd_table *)basetable;
+	msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX);
+	le32enc(table->bbarea + pp->sectorsize + 60, msize); /* d_secperunit */
+	basetable->gpt_last = msize - 1;
+	LIST_FOREACH(baseentry, &basetable->gpt_entry, gpe_entry) {
+		if (baseentry->gpe_index != RAW_PART + 1)
+			continue;
+		baseentry->gpe_end = basetable->gpt_last;
+		entry = (struct g_part_bsd_entry *)baseentry;
+		entry->part.p_size = msize;
+		return;
+	}
+}
+
 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;
+	struct g_provider *pp;
 
+	if (baseentry == NULL) {
+		pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
+		bsd_set_rawsize(basetable, pp);
+		return (0);
+	}
 	entry = (struct g_part_bsd_entry *)baseentry;
 	baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
 	entry->part.p_size = gpp->gpp_size;

Modified: stable/10/sys/geom/part/g_part_ebr.c
==============================================================================
--- stable/10/sys/geom/part/g_part_ebr.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part_ebr.c	Mon May 12 12:04:44 2014	(r265912)
@@ -93,6 +93,8 @@ static int g_part_ebr_setunset(struct g_
 static const char *g_part_ebr_type(struct g_part_table *, struct g_part_entry *,
     char *, size_t);
 static int g_part_ebr_write(struct g_part_table *, struct g_consumer *);
+static int g_part_ebr_resize(struct g_part_table *, struct g_part_entry *,
+    struct g_part_parms *);
 
 static kobj_method_t g_part_ebr_methods[] = {
 	KOBJMETHOD(g_part_add,		g_part_ebr_add),
@@ -108,6 +110,7 @@ static kobj_method_t g_part_ebr_methods[
 	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_resize,	g_part_ebr_resize),
 	KOBJMETHOD(g_part_setunset,	g_part_ebr_setunset),
 	KOBJMETHOD(g_part_type,		g_part_ebr_type),
 	KOBJMETHOD(g_part_write,	g_part_ebr_write),
@@ -384,6 +387,20 @@ g_part_ebr_modify(struct g_part_table *b
 	return (0);
 }
 
+static int
+g_part_ebr_resize(struct g_part_table *basetable,
+    struct g_part_entry *baseentry, struct g_part_parms *gpp)
+{
+	struct g_provider *pp;
+
+	if (baseentry != NULL)
+		return (EOPNOTSUPP);
+	pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
+	basetable->gpt_last = MIN(pp->mediasize / pp->sectorsize,
+	    UINT32_MAX) - 1;
+	return (0);
+}
+
 static const char *
 g_part_ebr_name(struct g_part_table *table, struct g_part_entry *entry,
     char *buf, size_t bufsz)

Modified: stable/10/sys/geom/part/g_part_gpt.c
==============================================================================
--- stable/10/sys/geom/part/g_part_gpt.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part_gpt.c	Mon May 12 12:04:44 2014	(r265912)
@@ -733,8 +733,11 @@ g_part_gpt_resize(struct g_part_table *b
     struct g_part_entry *baseentry, struct g_part_parms *gpp)
 {
 	struct g_part_gpt_entry *entry;
-	entry = (struct g_part_gpt_entry *)baseentry;
 
+	if (baseentry == NULL)
+		return (EOPNOTSUPP);
+
+	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;
 

Modified: stable/10/sys/geom/part/g_part_mbr.c
==============================================================================
--- stable/10/sys/geom/part/g_part_mbr.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part_mbr.c	Mon May 12 12:04:44 2014	(r265912)
@@ -345,6 +345,12 @@ g_part_mbr_resize(struct g_part_table *b
 	struct g_provider *pp;
 	uint32_t size;
 
+	if (baseentry == NULL) {
+		pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
+		basetable->gpt_last = MIN(pp->mediasize / pp->sectorsize,
+		    UINT32_MAX) - 1;
+		return (0);
+	}
 	size = gpp->gpp_size;
 	if (mbr_align(basetable, NULL, &size) != 0)
 		return (EINVAL);

Modified: stable/10/sys/geom/part/g_part_pc98.c
==============================================================================
--- stable/10/sys/geom/part/g_part_pc98.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part_pc98.c	Mon May 12 12:04:44 2014	(r265912)
@@ -352,6 +352,12 @@ g_part_pc98_resize(struct g_part_table *
 	struct g_provider *pp;
 	uint32_t size;
 
+	if (baseentry == NULL) {
+		pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
+		basetable->gpt_last = MIN(pp->mediasize / SECSIZE,
+		    UINT32_MAX) - 1;
+		return (0);
+	}
 	size = gpp->gpp_size;
 	if (pc98_align(basetable, NULL, &size) != 0)
 		return (EINVAL);

Modified: stable/10/sys/geom/part/g_part_vtoc8.c
==============================================================================
--- stable/10/sys/geom/part/g_part_vtoc8.c	Mon May 12 11:14:07 2014	(r265911)
+++ stable/10/sys/geom/part/g_part_vtoc8.c	Mon May 12 12:04:44 2014	(r265912)
@@ -317,6 +317,42 @@ g_part_vtoc8_modify(struct g_part_table 
 }
 
 static int
+vtoc8_set_rawsize(struct g_part_table *basetable, struct g_provider *pp)
+{
+	struct g_part_vtoc8_table *table;
+	struct g_part_entry *baseentry;
+	off_t msize;
+	uint32_t acyls, ncyls, pcyls;
+
+	table = (struct g_part_vtoc8_table *)basetable;
+	msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX);
+	pcyls = msize / table->secpercyl;
+	if (pcyls > UINT16_MAX)
+		return (ERANGE);
+	acyls = be16dec(&table->vtoc.altcyls);
+	ncyls = pcyls - acyls;
+	msize = ncyls * table->secpercyl;
+	basetable->gpt_last = msize - 1;
+
+	bzero(table->vtoc.ascii, sizeof(table->vtoc.ascii));
+	sprintf(table->vtoc.ascii, "FreeBSD%lldM cyl %u alt %u hd %u sec %u",
+	    (long long)(msize / 2048), ncyls, acyls, basetable->gpt_heads,
+	    basetable->gpt_sectors);
+	be16enc(&table->vtoc.physcyls, pcyls);
+	be16enc(&table->vtoc.ncyls, ncyls);
+	be32enc(&table->vtoc.map[VTOC_RAW_PART].nblks, msize);
+	if (be32dec(&table->vtoc.sanity) == VTOC_SANITY)
+		be16enc(&table->vtoc.part[VTOC_RAW_PART].tag, VTOC_TAG_BACKUP);
+	LIST_FOREACH(baseentry, &basetable->gpt_entry, gpe_entry) {
+		if (baseentry->gpe_index == VTOC_RAW_PART + 1) {
+			baseentry->gpe_end = basetable->gpt_last;
+			return (0);
+		}
+	}
+	return (ENXIO);
+}
+
+static int
 g_part_vtoc8_resize(struct g_part_table *basetable,
     struct g_part_entry *entry, struct g_part_parms *gpp)
 {
@@ -324,6 +360,10 @@ g_part_vtoc8_resize(struct g_part_table 
 	struct g_provider *pp;
 	uint64_t size;
 
+	if (entry == NULL) {
+		pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
+		return (vtoc8_set_rawsize(basetable, pp));
+	}
 	table = (struct g_part_vtoc8_table *)basetable;
 	size = gpp->gpp_size;
 	if (vtoc8_align(table, NULL, &size) != 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405121204.s4CC4j39099322>