Module Name:    src
Committed By:   christos
Date:           Sat Nov  9 16:40:38 UTC 2019

Modified Files:
        src/sys/sys: disklabel.h

Log Message:
Add a rather long comment explaining what has happened with disklabel and
why.


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/sys/disklabel.h

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

Modified files:

Index: src/sys/sys/disklabel.h
diff -u src/sys/sys/disklabel.h:1.120 src/sys/sys/disklabel.h:1.121
--- src/sys/sys/disklabel.h:1.120	Mon Nov  5 23:04:34 2018
+++ src/sys/sys/disklabel.h	Sat Nov  9 11:40:38 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: disklabel.h,v 1.120 2018/11/06 04:04:34 mrg Exp $	*/
+/*	$NetBSD: disklabel.h,v 1.121 2019/11/09 16:40:38 christos Exp $	*/
 
 /*
  * Copyright (c) 1987, 1988, 1993
@@ -116,6 +116,40 @@ struct	partition {		/* the partition tab
 #define	p_cpg	__partition_u1.cpg
 #define	p_sgs	__partition_u1.sgs
 };
+
+/*
+ * We'd rather have disklabel be the same size on 32 and 64 bit systems
+ * but it really isn't. In revision 108 matt@ tried to do that by adding
+ * un_d_pad as a uint64_t. This was really smart because the net effect
+ * as to grow the struct by 4 bytes on most LP32 machines and make it
+ * the same as LP64 without changing the layout (which is a nono because
+ * it is stored on existing disks). The easy way would have been to add
+ * padding at the end, but that would have been confusing (although that
+ * is what actually happens), because the partitions structure is supposed
+ * to be variable size and putting a padding uint32_t would be weird.
+ * Unfornately mips32 and i386 align uint64_t standalone at an 8 byte
+ * boundary, but in structures at a 4 byte boundary so matt's
+ * change did not affect them.
+ *
+ * We also prefer to have the structure 4 byte aligned so that the
+ * subr_disk_mbr.c code that scans for label does not trigger ubsan
+ * when comparing magic (without making the code ugly). To do this
+ * we can unexpose the d_boot{0,1} pointers in the kernel (so that
+ * LP64 systems can become 4 byte aligned) and at the same time
+ * remove the un_d_pad member and add padding at the end. The d_boot{0,1}
+ * fields are only used in userland in getdiskbyname(3), filled with
+ * the names of the primary and secondary bootstrap from /etc/disktab.
+ *
+ * While this is a way forward, it is not clear that it is the best
+ * way forward. The ubsan warning is incorrect and the code
+ * will always work since d_magic is always 4 byte aligned even
+ * when structure disklabel is not 8 byte aligned, so what we do
+ * now is ignore it. Another way would be to do offset arithmetic
+ * on the pointer and use it as a char *. That would not prevent
+ * other misaligned accesses in the future. Finally one could
+ * copy the unaligned structure to an aligned one, but that eats
+ * up space on the stack.
+ */
 struct disklabel {
 	uint32_t d_magic;		/* the magic number */
 	uint16_t d_type;		/* drive type */

Reply via email to