git: e77ef47d3649 - main - geom_label: Partially reinstate old sysinstall(8) workaround

Jessica Clarke jrtc27 at FreeBSD.org
Wed Jul 21 01:51:49 UTC 2021


The branch main has been updated by jrtc27:

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

commit e77ef47d3649090904e36a6ffa42486a435ba127
Author:     Jessica Clarke <jrtc27 at FreeBSD.org>
AuthorDate: 2021-07-21 01:24:55 +0000
Commit:     Jessica Clarke <jrtc27 at FreeBSD.org>
CommitDate: 2021-07-21 01:51:25 +0000

    geom_label: Partially reinstate old sysinstall(8) workaround
    
    This partially reverts commit af433832f7520840c22edd1fe1266c1a5cb781ad.
    Since such bogus disklabels still exist in the wild, we now probe for a
    disklabel to decide whether to ignore the UFS partition or not; if there
    is a label then we use the old behaviour, and if there isn't one then we
    use the new behaviour.
    
    Reviewed by:    cy, mckusick
    Differential Revision:  https://reviews.freebsd.org/D31068
---
 sys/geom/label/g_label_ufs.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/sys/geom/label/g_label_ufs.c b/sys/geom/label/g_label_ufs.c
index 70d59488d7b6..b29a04c9f348 100644
--- a/sys/geom/label/g_label_ufs.c
+++ b/sys/geom/label/g_label_ufs.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/disklabel.h>
 #include <sys/malloc.h>
 #include <sys/vnode.h>
 
@@ -48,6 +49,81 @@ __FBSDID("$FreeBSD$");
 #define	G_LABEL_UFS_VOLUME	0
 #define	G_LABEL_UFS_ID		1
 
+/*
+ * G_LABEL_UFS_CMP returns true if difference between provider mediasize
+ * and filesystem size is less than G_LABEL_UFS_MAXDIFF sectors
+ */
+#define	G_LABEL_UFS_CMP(prov, fsys, size) 				   \
+	( abs( ((fsys)->size) - ( (prov)->mediasize / (fsys)->fs_fsize ))  \
+				< G_LABEL_UFS_MAXDIFF )
+#define	G_LABEL_UFS_MAXDIFF	0x100
+
+/*
+ * For providers that look like disklabels we need to check if the file system
+ * size is almost equal to the provider's size, because sysinstall(8) used to
+ * bogusly put the first partition at offset 0 instead of 16, and glabel/ufs
+ * would find a file system on the slice instead of the partition.
+ *
+ * In addition, media size can be a bit bigger than file system size. For
+ * instance, mkuzip can append bytes to align data to large sector size (it
+ * improves compression rates).
+ */
+static bool
+g_label_ufs_ignore_bsdlabel_slice(struct g_consumer *cp,
+    struct fs *fs)
+{
+	struct g_provider *pp;
+	u_char *buf;
+	uint32_t magic1, magic2;
+	int error;
+
+	pp = cp->provider;
+
+	/*
+	 * If the expected provider size for the filesystem matches the
+	 * real provider size then don't ignore this filesystem.
+	 */
+	if (G_LABEL_UFS_CMP(pp, fs, fs_providersize))
+		return (false);
+
+	/*
+	 * If the filesystem size matches the real provider size then
+	 * don't ignore this filesystem.
+	 */
+	if (fs->fs_magic == FS_UFS1_MAGIC ?
+	    G_LABEL_UFS_CMP(pp, fs, fs_old_size) :
+	    G_LABEL_UFS_CMP(pp, fs, fs_size))
+		return (false);
+
+	/*
+	 * Provider is bigger than expected; probe to see if there's a
+	 * disklabel. Adapted from g_part_bsd_probe.
+	 */
+
+	/* Check if the superblock overlaps where the disklabel lives. */
+	if (fs->fs_sblockloc < pp->sectorsize * 2)
+		return (false);
+
+	/* Sanity-check the provider. */
+	if (pp->sectorsize < sizeof(struct disklabel) ||
+	    pp->mediasize < BBSIZE)
+		return (false);
+	if (BBSIZE % pp->sectorsize)
+		return (false);
+
+	/* Check that there's a disklabel. */
+	buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error);
+	if (buf == NULL)
+		return (false);
+	magic1 = le32dec(buf + 0);
+	magic2 = le32dec(buf + 132);
+	g_free(buf);
+	if (magic1 == DISKMAGIC && magic2 == DISKMAGIC)
+		return (true);
+
+	return (false);
+}
+
 /*
  * Try to find a superblock on the provider. If successful, look for a volume
  * label and create an appropriate provider based on that.
@@ -78,6 +154,9 @@ g_label_ufs_taste_common(struct g_consumer *cp, char *label, size_t size, int wh
 	} else {
 		goto out;
 	}
+	/* Check if this should be ignored for compatibility. */
+	if (g_label_ufs_ignore_bsdlabel_slice(cp, fs))
+		goto out;
 	G_LABEL_DEBUG(1, "%s file system detected on %s.",
 	    fs->fs_magic == FS_UFS1_MAGIC ? "UFS1" : "UFS2", pp->name);
 	switch (what) {


More information about the dev-commits-src-main mailing list