Module Name:    src
Committed By:   tsutsui
Date:           Sat Apr  7 03:08:33 UTC 2012

Modified Files:
        src/distrib/utils/sysinst: mbr.c

Log Message:
Use 1MB alignment rather than the default 63 sectors for
fdisk partition boundary for >128GB disks, as fdisk(8) does.
No particular comments for my PR install/45990.


To generate a diff of this commit:
cvs rdiff -u -r1.89 -r1.90 src/distrib/utils/sysinst/mbr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/utils/sysinst/mbr.c
diff -u src/distrib/utils/sysinst/mbr.c:1.89 src/distrib/utils/sysinst/mbr.c:1.90
--- src/distrib/utils/sysinst/mbr.c:1.89	Thu Jan  5 21:29:24 2012
+++ src/distrib/utils/sysinst/mbr.c	Sat Apr  7 03:08:33 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: mbr.c,v 1.89 2012/01/05 21:29:24 christos Exp $ */
+/*	$NetBSD: mbr.c,v 1.90 2012/04/07 03:08:33 tsutsui Exp $ */
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -113,6 +113,10 @@ static int get_mapping(struct mbr_partit
 			    daddr_t *);
 static void convert_mbr_chs(int, int, int, uint8_t *, uint8_t *,
 				 uint8_t *, uint32_t);
+static void get_ptn_alignment(struct mbr_partition *);
+
+static unsigned int ptn_alignment;
+static unsigned int ptn_0_offset;
 
 /*
  * Notes on the extended partition editor.
@@ -462,8 +466,9 @@ set_mbr_type(menudesc *m, void *arg)
 			return 0;
 		mbri->extended = ext;
 		ext->sector = mbrp->mbrp_start;
-		ext->mbr.mbr_parts[0].mbrp_start = bsec;
-		ext->mbr.mbr_parts[0].mbrp_size = mbrp->mbrp_size - bsec;
+		ext->mbr.mbr_parts[0].mbrp_start = ptn_0_offset;
+		ext->mbr.mbr_parts[0].mbrp_size =
+		    mbrp->mbrp_size - ptn_0_offset;
 	}
 	mbrp->mbrp_type = type;
 
@@ -742,14 +747,14 @@ edit_mbr_size(menudesc *m, void *arg)
 			/* If unchanged, don't re-round size */
 			new = dflt;
 		else {
-			/* Round end to cylinder boundary */
+			/* Round end to the partition alignment */
 			if (sizemult != 1) {
 				new *= sizemult;
-				new += rounddown(start, current_cylsize);
-				new = roundup(new, current_cylsize);
+				new += rounddown(start, ptn_alignment);
+				new = roundup(new, ptn_alignment);
 				new -= start;
 				while (new <= 0)
-					new += current_cylsize;
+					new += ptn_alignment;
 			}
 		}
 		if (new > max)
@@ -1237,12 +1242,12 @@ mbr_use_wholedisk(mbr_info_t *mbri)
 	memset(&mbri->mbrb, 0, sizeof mbri->mbrb);
 #endif
 	part[0].mbrp_type = MBR_PTYPE_NETBSD;
-	part[0].mbrp_size = dlsize - bsec;
-	part[0].mbrp_start = bsec;
+	part[0].mbrp_size = dlsize - ptn_0_offset;
+	part[0].mbrp_start = ptn_0_offset;
 	part[0].mbrp_flag = MBR_PFLAG_ACTIVE;
 
-	ptstart = bsec;
-	ptsize = dlsize - bsec;
+	ptstart = ptn_0_offset;
+	ptsize = dlsize - ptn_0_offset;
 	return 1;
 }
 
@@ -1450,6 +1455,10 @@ read_mbr(const char *disk, mbr_info_t *m
 	 */
 	if (bsec == 0)
 		bsec = dlsec;
+	ptn_0_offset = bsec;
+	/* use 1MB default offset on large disks as fdisk(8) */
+	if (dlsize > 2048 * 1024 * 128)
+		ptn_0_offset = 2048;
 
 	memset(mbri, 0, sizeof *mbri);
 
@@ -1467,7 +1476,9 @@ read_mbr(const char *disk, mbr_info_t *m
 			break;
 
 		mbrp = &mbrs->mbr_parts[0];
-		if (ext_base != 0) {
+		if (ext_base == 0) {
+			get_ptn_alignment(mbrp);
+		} else {
 			/* sanity check extended chain */
 			if (MBR_IS_EXTENDED(mbrp[0].mbrp_type))
 				break;
@@ -1547,9 +1558,9 @@ read_mbr(const char *disk, mbr_info_t *m
 				ext->sector = base;
 				ext->mbr.mbr_magic = htole16(MBR_MAGIC);
 				ext->mbr.mbr_parts[1] = mbrp[1];
-				ext->mbr.mbr_parts[0].mbrp_start = bsec;
+				ext->mbr.mbr_parts[0].mbrp_start = ptn_0_offset;
 				ext->mbr.mbr_parts[0].mbrp_size =
-				    ext_base + limit - base - bsec;
+				    ext_base + limit - base - ptn_0_offset;
 				mbrp[1].mbrp_type = MBR_PTYPE_EXT;
 				mbrp[1].mbrp_start = base - ext_base;
 				mbrp[1].mbrp_size = limit - mbrp[1].mbrp_start;
@@ -1850,3 +1861,36 @@ get_mapping(struct mbr_partition *parts,
 
 	return 0;
 }
+
+/*
+ * Determine partition boundary alignment as fdisk(8) does.
+ */
+static void
+get_ptn_alignment(struct mbr_partition *mbrp0)
+{
+	uint32_t ptn_0_base, ptn_0_limit;
+
+	/* Default to using 'traditional' cylinder alignment */
+	ptn_alignment = bhead * bsec;
+	ptn_0_offset = bsec;
+
+	if (mbrp0->mbrp_type != 0) {
+		/* Try to copy offset of first partition */
+		ptn_0_base = le32toh(mbrp0->mbrp_start);
+		ptn_0_limit = ptn_0_base + le32toh(mbrp0->mbrp_size);
+		if (!(ptn_0_limit & 2047)) {
+			/* Partition ends on a 1MB boundary, align to 1MB */
+			ptn_alignment = 2048;
+			if (ptn_0_base <= 2048
+			    && !(ptn_0_base & (ptn_0_base - 1))) {
+				/* ptn_base is a power of 2, use it */
+				ptn_0_offset = ptn_0_base;
+			}
+		}
+	} else {
+		/* Use 1MB offset for large (>128GB) disks */
+		if (dlsize > 2048 * 1024 * 128)
+			ptn_alignment = 2048;
+			ptn_0_offset = 2048;
+	}
+}

Reply via email to