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-all
mailing list