From owner-svn-src-all@FreeBSD.ORG Mon May 12 12:04:46 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DE192A48; Mon, 12 May 2014 12:04:46 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BEC472E29; Mon, 12 May 2014 12:04:46 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4CC4kRs099332; Mon, 12 May 2014 12:04:46 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4CC4j39099322; Mon, 12 May 2014 12:04:45 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201405121204.s4CC4j39099322@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Mon, 12 May 2014 12:04:45 +0000 (UTC) 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 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 May 2014 12:04:47 -0000 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)