summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2006-08-08 21:33:26 +0000
committermarcel <marcel@FreeBSD.org>2006-08-08 21:33:26 +0000
commite4aeb824edb92dc2f2c3508d8f32e6fd375644ad (patch)
treeb633d1c93da060c2b07efbe440fc48fd2d38e26c /sys/geom
parent7d23f1583e6ad8f51cc1aecedac76d865aeeed03 (diff)
downloadFreeBSD-src-e4aeb824edb92dc2f2c3508d8f32e6fd375644ad.zip
FreeBSD-src-e4aeb824edb92dc2f2c3508d8f32e6fd375644ad.tar.gz
Fix a phase-ordering bug: check the mediasize and sectorsize after
we obtained access. It is possible that GPT gets to taste a disk first, which means the disk has not been opened before and it will not get opened until after we checked the mediasize and sectorsize. However, since the mediasize and sectorsize are determined at open and that happens when access is optained, checking the mediasize and sectorsize before obtaining access may result in GPT rejecting the disk.
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_gpt.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/sys/geom/geom_gpt.c b/sys/geom/geom_gpt.c
index 24aa3c9..92b8371 100644
--- a/sys/geom/geom_gpt.c
+++ b/sys/geom/geom_gpt.c
@@ -931,26 +931,6 @@ g_gpt_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
g_topology_assert();
/*
- * Sanity-check the provider. Since the first sector on the provider
- * must be a PMBR and a PMBR is 512 bytes large, the sector size must
- * be at least 512 bytes. We also require that the sector size is a
- * multiple of the GPT entry size (which is 128 bytes).
- * Also, since the theoretical minimum number of sectors needed by
- * GPT is 6, any medium that has less than 6 sectors is never going
- * to hold a GPT. The number 6 comes from:
- * 1 sector for the PMBR
- * 2 sectors for the GPT headers (each 1 sector)
- * 2 sectors for the GPT tables (each 1 sector)
- * 1 sector for an actual partition
- * It's better to catch this pathological case early than behaving
- * pathologically later on by panicing...
- */
- if (pp->sectorsize < 512 ||
- pp->sectorsize % sizeof(struct gpt_ent) != 0 ||
- pp->mediasize < 6 * pp->sectorsize)
- return (NULL);
-
- /*
* We don't nest. That is, we disallow nesting a GPT inside a GPT
* partition. We check only for direct nesting. Indirect nesting is
* not easy to determine. If you want, you can therefore nest GPT
@@ -981,6 +961,27 @@ g_gpt_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
g_topology_unlock();
/*
+ * Now that we have access permissions, we can sanity-check the
+ * provider. Since the first sector on the provider must be a PMBR
+ * and a PMBR is 512 bytes large, the sector size must be at least
+ * 512 bytes. We also require that the sector size is a multiple
+ * of the GPT entry size (which is 128 bytes). Lastly, since the
+ * theoretical minimum number of sectors needed by GPT is 6, any
+ * medium that has less than 6 sectors is never going to be able
+ * to hold a GPT. The number 6 comes from:
+ * 1 sector for the PMBR
+ * 2 sectors for the GPT headers (each 1 sector)
+ * 2 sectors for the GPT tables (each 1 sector)
+ * 1 sector for an actual partition
+ * It's better to catch this pathological case early than behaving
+ * pathologically later on by panicing...
+ */
+ if (pp->sectorsize < 512 ||
+ pp->sectorsize % sizeof(struct gpt_ent) != 0 ||
+ pp->mediasize < 6 * pp->sectorsize)
+ goto fail;
+
+ /*
* Read both the primary and secondary GPT headers. We have all
* the information at our fingertips that way to determine if
* there's a GPT, including whether recovery is appropriate.
OpenPOWER on IntegriCloud