aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/part/g_part_ldm.c
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2012-03-29 06:37:02 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2012-03-29 06:37:02 +0000
commit1c45872b03260ebaf33193f800947d9ffb708cdb (patch)
tree1cb9a6aedb309140bf31c9592d1ea729a3736bb6 /sys/geom/part/g_part_ldm.c
parentf8727698eb609baaed6b9920745477e26ea6c0a7 (diff)
downloadsrc-1c45872b03260ebaf33193f800947d9ffb708cdb.tar.gz
src-1c45872b03260ebaf33193f800947d9ffb708cdb.zip
Do proper cleanup for the GPT case when an error occurs.
Notes
Notes: svn path=/head/; revision=233651
Diffstat (limited to 'sys/geom/part/g_part_ldm.c')
-rw-r--r--sys/geom/part/g_part_ldm.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/sys/geom/part/g_part_ldm.c b/sys/geom/part/g_part_ldm.c
index 6f5939c91bb9..dfd1a91c3ec4 100644
--- a/sys/geom/part/g_part_ldm.c
+++ b/sys/geom/part/g_part_ldm.c
@@ -1371,14 +1371,15 @@ g_part_ldm_read(struct g_part_table *basetable, struct g_consumer *cp)
/* Read and parse LDM private headers. */
error = ldm_privhdr_check(&db, cp, table->is_gpt);
if (error != 0)
- return (error);
+ goto gpt_cleanup;
basetable->gpt_first = table->is_gpt ? 0: db.ph.start;
basetable->gpt_last = basetable->gpt_first + db.ph.size - 1;
table->db_offset = db.ph.db_offset;
/* Make additional checks for GPT */
if (table->is_gpt) {
- if (ldm_gpt_check(&db, cp) != 0)
- return (ENXIO);
+ error = ldm_gpt_check(&db, cp);
+ if (error != 0)
+ goto gpt_cleanup;
/*
* Now we should reset database offset to zero, because our
* consumer cp is attached to the ms-ldm-metadata partition
@@ -1389,12 +1390,25 @@ g_part_ldm_read(struct g_part_table *basetable, struct g_consumer *cp)
/* Read and parse LDM TOC headers. */
error = ldm_tochdr_check(&db, cp);
if (error != 0)
- return (error);
+ goto gpt_cleanup;
/* Read and parse LDM VMDB header. */
error = ldm_vmdbhdr_check(&db, cp);
if (error != 0)
- return (error);
+ goto gpt_cleanup;
error = ldm_vmdb_parse(&db, cp);
+ /*
+ * For the GPT case we must detach and destroy
+ * second consumer before return.
+ */
+gpt_cleanup:
+ if (table->is_gpt) {
+ g_topology_lock();
+ g_access(cp, -1, 0, 0);
+ g_detach(cp);
+ g_destroy_consumer(cp);
+ g_topology_unlock();
+ cp = cp2;
+ }
if (error != 0)
return (error);
/* Search current disk in the disk list. */
@@ -1408,15 +1422,6 @@ g_part_ldm_read(struct g_part_table *basetable, struct g_consumer *cp)
ldm_vmdb_free(&db);
return (ENXIO);
}
- if (table->is_gpt) {
- /* Second consumer is no longer needed. */
- g_topology_lock();
- g_access(cp, -1, 0, 0);
- g_detach(cp);
- g_destroy_consumer(cp);
- g_topology_unlock();
- cp = cp2;
- }
index = 1;
LIST_FOREACH(vol, &db.volumes, entry) {
LIST_FOREACH(comp, &vol->components, entry) {