summaryrefslogtreecommitdiffstats
path: root/sys/geom/part
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2010-04-25 00:54:11 +0000
committermarcel <marcel@FreeBSD.org>2010-04-25 00:54:11 +0000
commit365394e3ab6337456981fbb1d6e3104011f4100d (patch)
treeae8e345ecb9d07ba35d598101f67db822372cb01 /sys/geom/part
parent819559822c8243b4df61561a96ce3e4d5c991461 (diff)
downloadFreeBSD-src-365394e3ab6337456981fbb1d6e3104011f4100d.zip
FreeBSD-src-365394e3ab6337456981fbb1d6e3104011f4100d.tar.gz
Fix undo for schemes that have internal partitions. Internal partitions
do not constitute user-visible or active partitions and as such should not prevent undoing pending operations. While here, initialize the last usable sector for the placeholder geom based on the null scheme, created to allow undoing the destruction of a scheme. This gives consistent output with "gpart show". Based on a patch from: "Andrey V. Elsukov" <bu7cher@yandex.ru>
Diffstat (limited to 'sys/geom/part')
-rw-r--r--sys/geom/part/g_part.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 9cddd0d..7a979da 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -855,7 +855,9 @@ g_part_ctl_delete(struct gctl_req *req, struct g_part_parms *gpp)
static int
g_part_ctl_destroy(struct gctl_req *req, struct g_part_parms *gpp)
{
+ struct g_consumer *cp;
struct g_geom *gp;
+ struct g_provider *pp;
struct g_part_entry *entry;
struct g_part_table *null, *table;
struct sbuf *sb;
@@ -885,6 +887,11 @@ g_part_ctl_destroy(struct gctl_req *req, struct g_part_parms *gpp)
null->gpt_gp = gp;
null->gpt_scheme = &g_part_null_scheme;
LIST_INIT(&null->gpt_entry);
+
+ cp = LIST_FIRST(&gp->consumer);
+ pp = cp->provider;
+ null->gpt_last = pp->mediasize / pp->sectorsize - 1;
+
null->gpt_depth = table->gpt_depth;
null->gpt_opened = table->gpt_opened;
null->gpt_smhead = table->gpt_smhead;
@@ -1141,10 +1148,16 @@ g_part_ctl_undo(struct gctl_req *req, struct g_part_parms *gpp)
table->gpt_created) ? 1 : 0;
if (reprobe) {
- if (!LIST_EMPTY(&table->gpt_entry)) {
+ LIST_FOREACH(entry, &table->gpt_entry, gpe_entry) {
+ if (entry->gpe_internal)
+ continue;
error = EBUSY;
goto fail;
}
+ while ((entry = LIST_FIRST(&table->gpt_entry)) != NULL) {
+ LIST_REMOVE(entry, gpe_entry);
+ g_free(entry);
+ }
error = g_part_probe(gp, cp, table->gpt_depth);
if (error) {
g_topology_lock();
OpenPOWER on IntegriCloud