Author: ae
Date: Thu Mar 29 06:37:02 2012
New Revision: 233651
URL: http://svn.freebsd.org/changeset/base/233651

Log:
  Do proper cleanup for the GPT case when an error occurs.

Modified:
  head/sys/geom/part/g_part_ldm.c

Modified: head/sys/geom/part/g_part_ldm.c
==============================================================================
--- head/sys/geom/part/g_part_ldm.c     Thu Mar 29 06:19:00 2012        
(r233650)
+++ head/sys/geom/part/g_part_ldm.c     Thu Mar 29 06:37:02 2012        
(r233651)
@@ -1371,14 +1371,15 @@ g_part_ldm_read(struct g_part_table *bas
        /* 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 *bas
        /* 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 *bas
                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) {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to