diff options
author | Andrey V. Elsukov <ae@FreeBSD.org> | 2012-03-29 06:37:02 +0000 |
---|---|---|
committer | Andrey V. Elsukov <ae@FreeBSD.org> | 2012-03-29 06:37:02 +0000 |
commit | 1c45872b03260ebaf33193f800947d9ffb708cdb (patch) | |
tree | 1cb9a6aedb309140bf31c9592d1ea729a3736bb6 /sys/geom/part/g_part_ldm.c | |
parent | f8727698eb609baaed6b9920745477e26ea6c0a7 (diff) | |
download | src-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.c | 33 |
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) { |