---
 drivers/md/dm-thin-metadata.c |  127 ++++++++++++++++++++++--------------------
 1 file changed, 69 insertions(+), 58 deletions(-)

Index: linux-3.0/drivers/md/dm-thin-metadata.c
===================================================================
--- linux-3.0.orig/drivers/md/dm-thin-metadata.c
+++ linux-3.0/drivers/md/dm-thin-metadata.c
@@ -497,7 +497,7 @@ bad:
 	return ERR_PTR(r);
 }
 
-static int begin_transaction(struct dm_pool_metadata *pmd)
+static int __begin_transaction(struct dm_pool_metadata *pmd)
 {
 	int r;
 	u32 features;
@@ -581,7 +581,7 @@ struct dm_pool_metadata *dm_pool_metadat
 	pmd->bdev = bdev;
 
 	if (!create) {
-		r = begin_transaction(pmd);
+		r = __begin_transaction(pmd);
 		if (r < 0)
 			goto bad;
 		return pmd;
@@ -591,7 +591,7 @@ struct dm_pool_metadata *dm_pool_metadat
 	 * Create.
 	 */
 	if (!pmd->sblock) {
-		r = begin_transaction(pmd);
+		r = __begin_transaction(pmd);
 		if (r < 0)
 			goto bad;
 	}
@@ -631,46 +631,6 @@ bad:
 	return ERR_PTR(r);
 }
 
-int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
-{
-	int r;
-	unsigned open_devices = 0;
-	struct dm_thin_device *td, *tmp;
-
-	down_read(&pmd->root_lock);
-	list_for_each_entry_safe(td, tmp, &pmd->thin_devices, list) {
-		if (td->open_count)
-			open_devices++;
-		else {
-			list_del(&td->list);
-			kfree(td);
-		}
-	}
-	up_read(&pmd->root_lock);
-
-	if (open_devices) {
-		DMERR("attempt to close pmd when %u device(s) are still open",
-		       open_devices);
-		return -EBUSY;
-	}
-
-	if (pmd->sblock) {
-		r = dm_pool_commit_metadata(pmd);
-		if (r)
-			DMWARN("%s: dm_pool_commit_metadata() failed, error = %d",
-			       __func__, r);
-	}
-
-	dm_tm_destroy(pmd->tm);
-	dm_tm_destroy(pmd->nb_tm);
-	dm_block_manager_destroy(pmd->bm);
-	dm_sm_destroy(pmd->metadata_sm);
-	dm_sm_destroy(pmd->data_sm);
-	kfree(pmd);
-
-	return 0;
-}
-
 int dm_pool_rebind_metadata_device(struct dm_pool_metadata *pmd,
 					 struct block_device *bdev)
 {
@@ -1193,36 +1153,30 @@ static int __write_changed_details(struc
 	return 0;
 }
 
-int dm_pool_commit_metadata(struct dm_pool_metadata *pmd)
+static int __commit_metadata(struct dm_pool_metadata *pmd)
 {
 	/*
-	 * FIXME: associated pool should be made read-only on
+	 * FIXME: Associated pool should be made read-only on
 	 * dm_pool_commit_metadata failure.
 	 */
 	int r;
 	size_t len;
 	struct thin_disk_superblock *disk_super;
 
-	/*
-	 * We need to know if the thin_disk_superblock exceeds a 512-byte sector.
-	 */
-	BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512);
-
-	down_write(&pmd->root_lock);
 	r = __write_changed_details(pmd);
 	if (r < 0)
-		goto out;
+		return r;
 
 	if (!pmd->need_commit)
-		goto out;
+		return r;
 
 	r = dm_tm_pre_commit(pmd->tm);
 	if (r < 0)
-		goto out;
+		return r;
 
 	r = dm_sm_root_size(pmd->metadata_sm, &len);
 	if (r < 0)
-		goto out;
+		return r;
 
 	disk_super = dm_block_data(pmd->sblock);
 	disk_super->time = cpu_to_le32(pmd->time);
@@ -1233,13 +1187,29 @@ int dm_pool_commit_metadata(struct dm_po
 
 	r = dm_sm_copy_root(pmd->metadata_sm, &disk_super->metadata_space_map_root, len);
 	if (r < 0)
-		goto out;
+		return r;
 
 	r = dm_sm_copy_root(pmd->data_sm, &disk_super->data_space_map_root, len);
 	if (r < 0)
-		goto out;
+		return r;
 
 	r = dm_tm_commit(pmd->tm, pmd->sblock);
+
+	return r;
+}
+
+int dm_pool_commit_metadata(struct dm_pool_metadata *pmd)
+{
+	int r;
+
+	/*
+	 * We need to know if the thin_disk_superblock exceeds a 512-byte sector.
+	 */
+	BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512);
+
+	down_write(&pmd->root_lock);
+
+	r = __commit_metadata(pmd);
 	if (r < 0)
 		goto out;
 
@@ -1248,12 +1218,53 @@ int dm_pool_commit_metadata(struct dm_po
 	 */
 	pmd->sblock = NULL;
 
-	r = begin_transaction(pmd);
+	r = __begin_transaction(pmd);
 out:
 	up_write(&pmd->root_lock);
+
 	return r;
 }
 
+int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
+{
+	int r;
+	unsigned open_devices = 0;
+	struct dm_thin_device *td, *tmp;
+
+	down_read(&pmd->root_lock);
+	list_for_each_entry_safe(td, tmp, &pmd->thin_devices, list) {
+		if (td->open_count)
+			open_devices++;
+		else {
+			list_del(&td->list);
+			kfree(td);
+		}
+	}
+	up_read(&pmd->root_lock);
+
+	if (open_devices) {
+		DMERR("attempt to close pmd when %u device(s) are still open",
+		       open_devices);
+		return -EBUSY;
+	}
+
+	if (pmd->sblock) {
+		r = dm_pool_commit_metadata(pmd);
+		if (r)
+			DMWARN("%s: dm_pool_commit_metadata() failed, error = %d",
+			       __func__, r);
+	}
+
+	dm_tm_destroy(pmd->tm);
+	dm_tm_destroy(pmd->nb_tm);
+	dm_block_manager_destroy(pmd->bm);
+	dm_sm_destroy(pmd->metadata_sm);
+	dm_sm_destroy(pmd->data_sm);
+	kfree(pmd);
+
+	return 0;
+}
+
 int dm_pool_get_free_block_count(struct dm_pool_metadata *pmd, dm_block_t *result)
 {
 	int r;