git: 7bdb67cb1cfe - releng/14.0 - gpart: Be less picky about GPT Tables in some cases

From: Warner Losh <imp_at_FreeBSD.org>
Date: Thu, 26 Oct 2023 23:22:28 UTC
The branch releng/14.0 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=7bdb67cb1cfe161de68bfe0cd35bab73d4c77e3c

commit 7bdb67cb1cfe161de68bfe0cd35bab73d4c77e3c
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2023-10-26 16:14:54 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-10-26 23:18:38 +0000

    gpart: Be less picky about GPT Tables in some cases
    
    When we're recoverying a damangae GPT, or when we're restoring a backed
    up partition tables, don't enforce the 4k alignment for start/end LBAs.
    This is useful for 512e/4kn drives when we're creating a new partition
    table or partition. However, when we're trying to fix / restore an old
    partition, we shouldn't force this alignment, since in that case it's
    more important to use the partition table as is than to optimize
    performance by rounding (which isn't required by the standard).
    
    MFC After:              1 week (pushed more quickly per re@)
    Sponsored by:           Netflix
    Differential Revision:  https://reviews.freebsd.org/D42359
    
    (cherry picked from commit 5c9f0f72f47ea5315e5147185e47c2efca2e8c85)
    (cherry picked from commit 859d674e1745d0a37c9c8d77e21a3fadd713ef49)
    Approved-by: re (gjb)
---
 sys/geom/part/g_part_gpt.c | 41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index 990ace4a25d4..c4cc840f583d 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -103,7 +103,8 @@ struct g_part_gpt_entry {
 
 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 void g_gpt_set_defaults(struct g_part_table *, struct g_provider *,
+    struct g_part_parms *);
 
 static int g_part_gpt_add(struct g_part_table *, struct g_part_entry *,
     struct g_part_parms *);
@@ -717,7 +718,7 @@ g_part_gpt_create(struct g_part_table *basetable, struct g_part_parms *gpp)
 	table->hdr->hdr_entries = basetable->gpt_entries;
 	table->hdr->hdr_entsz = sizeof(struct gpt_ent);
 
-	g_gpt_set_defaults(basetable, pp);
+	g_gpt_set_defaults(basetable, pp, gpp);
 	return (0);
 }
 
@@ -1083,7 +1084,7 @@ g_part_gpt_recover(struct g_part_table *basetable)
 	table = (struct g_part_gpt_table *)basetable;
 	pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
 	gpt_create_pmbr(table, pp);
-	g_gpt_set_defaults(basetable, pp);
+	g_gpt_set_defaults(basetable, pp, NULL);
 	basetable->gpt_corrupt = 0;
 	return (0);
 }
@@ -1300,7 +1301,8 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp)
 }
 
 static void
-g_gpt_set_defaults(struct g_part_table *basetable, struct g_provider *pp)
+g_gpt_set_defaults(struct g_part_table *basetable, struct g_provider *pp,
+	struct g_part_parms *gpp)
 {
 	struct g_part_entry *baseentry;
 	struct g_part_gpt_entry *entry;
@@ -1334,14 +1336,29 @@ g_gpt_set_defaults(struct g_part_table *basetable, struct g_provider *pp)
 		if (entry->ent.ent_lba_end > max)
 			max = entry->ent.ent_lba_end;
 	}
-	spb = 4096 / pp->sectorsize;
-	if (spb > 1) {
-		lba = start + ((start % spb) ? spb - start % spb : 0);
-		if (lba <= min)
-			start = lba;
-		lba = end - (end + 1) % spb;
-		if (max <= lba)
-			end = lba;
+	/*
+	 * Don't force alignment of any kind whatsoever on resize, restore or
+	 * recover. resize doesn't go through this path, recover has a NULL gpp
+	 * and restore has flags == restore (maybe with an appended 'C' to
+	 * commit the operation). For these operations, we have to trust the
+	 * user knows what they are doing.
+	 *
+	 * Otherwise it some flavor of creation of a new partition, so we align
+	 * to a 4k offset on the drive, to make 512e/4kn drives more performant
+	 * by default.
+	 */
+	if (gpp == NULL ||
+	    (gpp->gpp_parms & G_PART_PARM_FLAGS) == 0 ||
+	    strstr(gpp->gpp_flags, "restore") == NULL) {
+		spb = 4096 / pp->sectorsize;
+		if (spb > 1) {
+			lba = start + ((start % spb) ? spb - start % spb : 0);
+			if (lba <= min)
+				start = lba;
+			lba = end - (end + 1) % spb;
+			if (max <= lba)
+				end = lba;
+		}
 	}
 	table->hdr->hdr_lba_start = start;
 	table->hdr->hdr_lba_end = end;