Page MenuHomeFreeBSD

D33168.id99174.diff
No OneTemporary

D33168.id99174.diff

Index: lib/geom/part/geom_part.c
===================================================================
--- lib/geom/part/geom_part.c
+++ lib/geom/part/geom_part.c
@@ -127,8 +127,10 @@
{ 's', "scheme", NULL, G_TYPE_STRING },
{ 'n', "entries", G_VAL_OPTIONAL, G_TYPE_NUMBER },
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
+ { 'l', "tblpri_start", G_VAL_OPTIONAL, G_TYPE_STRING },
+ { 'L', "tblsec_start", G_VAL_OPTIONAL, G_TYPE_STRING },
G_OPT_SENTINEL },
- "-s scheme [-n entries] [-f flags] provider"
+ "-s scheme [-l/-L start pri/sec table] [-n entries] [-f flags] provider"
},
{ "delete", 0, gpart_issue, {
{ 'i', GPART_PARAM_INDEX, NULL, G_TYPE_NUMBER },
Index: lib/geom/part/gpart.8
===================================================================
--- lib/geom/part/gpart.8
+++ lib/geom/part/gpart.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 17, 2020
+.Dd November 29, 2021
.Dt GPART 8
.Os
.Sh NAME
@@ -64,6 +64,8 @@
.Fl s Ar scheme
.Op Fl n Ar entries
.Op Fl f Ar flags
+.Op Fl l Ar pritbl
+.Op Fl L Ar sectbl
.Ar provider
.\" ==== DELETE ====
.Nm
@@ -302,6 +304,24 @@
The kernel must have support for a particular scheme before
that scheme can be used to partition a disk.
.El
+.Pp
+In addition the
+.Cd GPT scheme
+accepts the following options to the
+.Cm create
+command:
+.Bl -tag -width 10n
+.It Fl l Ar pritbl
+The offset in bytes where the primary GPT partition table will begin.
+This can be useful for embedded devices which want to place firmware
+in the low blocks but still allow the first two disk sectors to be used
+for the pmbr and the primary GPT partition header.
+An SI unit suffix is not allowed.
+.It Fl L Ar sectbl
+The offset in bytes where the secondary GPT partition table will begin
+(growing backwards).
+An SI unit suffix is not allowed.
+.El
.\" ==== DELETE ====
.It Cm delete
Delete a partition from geom
Index: sys/geom/part/g_part.h
===================================================================
--- sys/geom/part/g_part.h
+++ sys/geom/part/g_part.h
@@ -145,6 +145,9 @@
quad_t gpt_first; /* First allocatable LBA */
quad_t gpt_last; /* Last allocatable LBA */
int gpt_entries;
+ /* Offset where to start the primary/secondary table (or 0). */
+ quad_t gpt_tblpri_start;
+ quad_t gpt_tblsec_start;
/*
* gpt_smhead and gpt_smtail are bitmaps representing the first
* 32 sectors on the disk (gpt_smhead) and the last 32 sectors
@@ -213,6 +216,8 @@
#define G_PART_PARM_ATTRIB 0x2000
#define G_PART_PARM_FORCE 0x4000
#define G_PART_PARM_SKIP_DSN 0x8000
+#define G_PART_PARM_TBLPRI_START 0x10000
+#define G_PART_PARM_TBLSEC_START 0x20000
struct g_part_parms {
unsigned int gpp_parms;
@@ -232,6 +237,8 @@
const char *gpp_attrib;
unsigned int gpp_force;
unsigned int gpp_skip_dsn;
+ quad_t gpp_tblpri_start;
+ quad_t gpp_tblsec_start;
};
void g_part_geometry_heads(off_t, u_int, off_t *, u_int *);
Index: sys/geom/part/g_part.c
===================================================================
--- sys/geom/part/g_part.c
+++ sys/geom/part/g_part.c
@@ -996,6 +996,20 @@
gctl_error(req, "%d entries '%d'", EINVAL, gpp->gpp_entries);
return (EINVAL);
}
+ if ((gpp->gpp_parms & G_PART_PARM_TBLPRI_START) &&
+ (gpp->gpp_tblpri_start < 256 ||
+ gpp->gpp_tblpri_start > pp->mediasize - 512)) {
+ gctl_error(req, "%d tblpri_start '%jd'", EINVAL,
+ (intmax_t)gpp->gpp_tblpri_start);
+ return (EINVAL);
+ }
+ if ((gpp->gpp_parms & G_PART_PARM_TBLSEC_START) &&
+ (gpp->gpp_tblsec_start < 512 ||
+ gpp->gpp_tblsec_start > pp->mediasize)) {
+ gctl_error(req, "%d tblsec_start '%jd'", EINVAL,
+ (intmax_t)gpp->gpp_tblsec_start);
+ return (EINVAL);
+ }
if (null == NULL)
gp = g_new_geomf(&g_part_class, "%s", pp->name);
@@ -1006,6 +1020,10 @@
table->gpt_scheme = gpp->gpp_scheme;
table->gpt_entries = (gpp->gpp_parms & G_PART_PARM_ENTRIES) ?
gpp->gpp_entries : scheme->gps_minent;
+ table->gpt_tblpri_start = (gpp->gpp_parms & G_PART_PARM_TBLPRI_START) ?
+ gpp->gpp_tblpri_start : 0;
+ table->gpt_tblsec_start = (gpp->gpp_parms & G_PART_PARM_TBLSEC_START) ?
+ gpp->gpp_tblsec_start : 0;
LIST_INIT(&table->gpt_entry);
if (null == NULL) {
cp = g_new_consumer(gp);
@@ -1642,6 +1660,8 @@
ctlreq = G_PART_CTL_CREATE;
mparms |= G_PART_PARM_PROVIDER | G_PART_PARM_SCHEME;
oparms |= G_PART_PARM_ENTRIES;
+ oparms |= G_PART_PARM_TBLPRI_START;
+ oparms |= G_PART_PARM_TBLSEC_START;
}
break;
case 'd':
@@ -1754,6 +1774,10 @@
case 't':
if (!strcmp(ap->name, "type"))
parm = G_PART_PARM_TYPE;
+ if (!strcmp(ap->name, "tblpri_start"))
+ parm = G_PART_PARM_TBLPRI_START;
+ if (!strcmp(ap->name, "tblsec_start"))
+ parm = G_PART_PARM_TBLSEC_START;
break;
case 'v':
if (!strcmp(ap->name, "verb"))
@@ -1818,6 +1842,14 @@
error = g_part_parm_quad(req, ap->name,
&gpp.gpp_start);
break;
+ case G_PART_PARM_TBLPRI_START:
+ error = g_part_parm_quad(req, ap->name,
+ &gpp.gpp_tblpri_start);
+ break;
+ case G_PART_PARM_TBLSEC_START:
+ error = g_part_parm_quad(req, ap->name,
+ &gpp.gpp_tblsec_start);
+ break;
case G_PART_PARM_TYPE:
error = g_part_parm_str(req, ap->name, &gpp.gpp_type);
break;
Index: sys/geom/part/g_part_gpt.c
===================================================================
--- sys/geom/part/g_part_gpt.c
+++ sys/geom/part/g_part_gpt.c
@@ -105,6 +105,7 @@
static void g_gpt_printf_utf16(struct sbuf *, uint16_t *, size_t);
static void g_gpt_utf8_to_utf16(const uint8_t *, uint16_t *, size_t);
static void g_gpt_set_defaults(struct g_part_table *, struct g_provider *);
+static int g_gpt_set_table_start(struct g_part_table *, struct g_provider *);
static int g_part_gpt_add(struct g_part_table *, struct g_part_entry *,
struct g_part_parms *);
@@ -681,6 +682,7 @@
struct g_provider *pp;
struct g_part_gpt_table *table;
size_t tblsz;
+ int error;
/* Our depth should be 0 unless nesting was explicitly enabled. */
if (!allow_nesting && basetable->gpt_depth != 0)
@@ -695,6 +697,11 @@
pp->sectorsize)
return (ENOSPC);
+ /* Do a pre-check. */
+ error = g_gpt_set_table_start(basetable, pp);
+ if (error != 0)
+ return (error);
+
gpt_create_pmbr(table, pp);
/* Allocate space for the header */
@@ -1282,6 +1289,41 @@
return (error);
}
+static int
+g_gpt_set_table_start(struct g_part_table *basetable, struct g_provider *pp)
+{
+ struct g_part_gpt_table *table;
+ quad_t lba, last;
+ size_t tblsz;
+
+ table = (struct g_part_gpt_table *)basetable;
+ last = pp->mediasize / pp->sectorsize - 1;
+ tblsz = howmany(basetable->gpt_entries * sizeof(struct gpt_ent),
+ pp->sectorsize);
+
+ /* Set defaults. */
+ table->lba[GPT_ELT_PRITBL] = 2;
+ table->lba[GPT_ELT_SECTBL] = last - tblsz;
+
+ if (basetable->gpt_tblpri_start != 0) {
+ lba = (basetable->gpt_tblpri_start % pp->sectorsize) ? 1 : 0;
+ lba += basetable->gpt_tblpri_start / pp->sectorsize;
+ if (lba < 2 || lba > last)
+ return (ENOSPC);
+ table->lba[GPT_ELT_PRITBL] = lba;
+ }
+
+ if (basetable->gpt_tblsec_start != 0) {
+ lba = (basetable->gpt_tblsec_start % pp->sectorsize) ? 1 : 0;
+ lba += basetable->gpt_tblsec_start / pp->sectorsize;
+ if (lba < 2 + tblsz || lba > last)
+ return (ENOSPC);
+ table->lba[GPT_ELT_SECTBL] = lba;
+ }
+
+ return (0);
+}
+
static void
g_gpt_set_defaults(struct g_part_table *basetable, struct g_provider *pp)
{
@@ -1298,16 +1340,15 @@
pp->sectorsize);
table->lba[GPT_ELT_PRIHDR] = 1;
- table->lba[GPT_ELT_PRITBL] = 2;
table->lba[GPT_ELT_SECHDR] = last;
- table->lba[GPT_ELT_SECTBL] = last - tblsz;
+ g_gpt_set_table_start(basetable, pp);
table->state[GPT_ELT_PRIHDR] = GPT_STATE_OK;
table->state[GPT_ELT_PRITBL] = GPT_STATE_OK;
table->state[GPT_ELT_SECHDR] = GPT_STATE_OK;
table->state[GPT_ELT_SECTBL] = GPT_STATE_OK;
- max = start = 2 + tblsz;
- min = end = last - tblsz - 1;
+ max = start = table->lba[GPT_ELT_PRITBL] + tblsz;
+ min = end = table->lba[GPT_ELT_SECTBL] - 1;
LIST_FOREACH(baseentry, &basetable->gpt_entry, gpe_entry) {
if (baseentry->gpe_deleted)
continue;

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 1, 8:41 AM (2 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34550758
Default Alt Text
D33168.id99174.diff (7 KB)

Event Timeline