[Ocfs2-tools-devel] [PATCH 2/2] libocfs2: Make allocating a specific cluster a clean API

Joel Becker joel.becker at oracle.com
Fri Nov 14 15:49:44 PST 2008


The backup superblock code hand-builds the necessary operations to load
the cluster allocator and set the backup superblock clusters.  Let's
create clean APIs for this in libocfs2/alloc.c and have backup_super.c
use them.

While we're at it, set_backup_super() used to free the cluster allocator
when it was done.  That doesn't fit with the library's standard "cache
that allocator" behavior.  So don't free it.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 include/ocfs2/ocfs2.h   |    3 ++
 libocfs2/alloc.c        |   39 +++++++++++++++++++++++++++
 libocfs2/backup_super.c |   67 ++++++----------------------------------------
 3 files changed, 51 insertions(+), 58 deletions(-)

diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 68ba4f5..e30d31d 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -511,6 +511,9 @@ errcode_t ocfs2_new_clusters(ocfs2_filesys *fs,
 			     uint32_t requested,
 			     uint64_t *start_blkno,
 			     uint32_t *clusters_found);
+errcode_t ocfs2_test_cluster_allocated(ocfs2_filesys *fs, uint32_t cpos,
+				       int *is_allocated);
+errcode_t ocfs2_new_specific_cluster(ocfs2_filesys *fs, uint32_t cpos);
 errcode_t ocfs2_free_clusters(ocfs2_filesys *fs,
 			      uint32_t len,
 			      uint64_t start_blkno);
diff --git a/libocfs2/alloc.c b/libocfs2/alloc.c
index 03b3091..2597c2f 100644
--- a/libocfs2/alloc.c
+++ b/libocfs2/alloc.c
@@ -491,6 +491,45 @@ out:
 	return ret;
 }
 
+errcode_t ocfs2_test_cluster_allocated(ocfs2_filesys *fs, uint32_t cpos,
+				       int *is_allocated)
+{
+	errcode_t ret;
+	ret = ocfs2_load_allocator(fs, GLOBAL_BITMAP_SYSTEM_INODE,
+				   0, &fs->fs_cluster_alloc);
+	if (!ret) {
+		ret = ocfs2_chain_test(fs, fs->fs_cluster_alloc, cpos,
+				       is_allocated);
+	}
+
+	return ret;
+}
+
+errcode_t ocfs2_new_specific_cluster(ocfs2_filesys *fs, uint32_t cpos)
+{
+	errcode_t ret;
+	int allocatedp = 0;
+
+	/* Loads the allocator if we need it */
+	ret = ocfs2_test_cluster_allocated(fs, cpos, &allocatedp);
+	if (ret)
+		goto out;
+
+	if (allocatedp) {
+		ret = OCFS2_ET_BIT_NOT_FOUND;
+		goto out;
+	}
+
+	ocfs2_chain_force_val(fs, fs->fs_cluster_alloc, cpos, 1, NULL);
+	ret = ocfs2_write_chain_allocator(fs, fs->fs_cluster_alloc);
+	if (ret)
+		ocfs2_free_clusters(fs, 1,
+				    ocfs2_blocks_to_clusters(fs, cpos));
+
+out:
+	return ret;
+}
+
 errcode_t ocfs2_free_clusters(ocfs2_filesys *fs,
 			      uint32_t len,
 			      uint64_t start_blkno)
diff --git a/libocfs2/backup_super.c b/libocfs2/backup_super.c
index 84b0449..4538b84 100644
--- a/libocfs2/backup_super.c
+++ b/libocfs2/backup_super.c
@@ -76,49 +76,23 @@ errcode_t ocfs2_clear_backup_super_list(ocfs2_filesys *fs,
 				      OCFS2_FEATURE_COMPAT_BACKUP_SB))
 		goto bail;
 
-	if (!fs->fs_cluster_alloc) {
-		loaded = 1;
-		ret = ocfs2_lookup_system_inode(fs, GLOBAL_BITMAP_SYSTEM_INODE,
-						0, &bm_blk);
-		if (ret)
-			goto bail;
-
-		ret = ocfs2_read_cached_inode(fs, bm_blk, &fs->fs_cluster_alloc);
-		if (ret)
-			goto bail;
-
-		ret = ocfs2_load_chain_allocator(fs, fs->fs_cluster_alloc);
-		if (ret)
-			goto bail;
-	}
 
 	for (i = 0; i < len; i++) {
-		ret = ocfs2_chain_free(fs,
-				       fs->fs_cluster_alloc,
-				       ocfs2_blocks_to_clusters(fs,
-								blocks[i]));
-		/* Ignore the 'bit was already free' error */
-		if (ret &&
-		    (ret != OCFS2_ET_FREEING_UNALLOCATED_REGION))
-			goto bail;
+		ret = ocfs2_free_clusters(fs, 1, blocks[i]);
+		if (ret)
+			break;
 	}
 
-	ret = ocfs2_write_chain_allocator(fs, fs->fs_cluster_alloc);
-
 bail:
-	if (fs->fs_cluster_alloc && loaded) {
-		ocfs2_free_cached_inode(fs, fs->fs_cluster_alloc);
-		fs->fs_cluster_alloc = NULL;
-	}
 	return ret;
 }
 
-static errcode_t check_cluster(ocfs2_bitmap *bitmap, uint64_t bit)
+static errcode_t check_cluster(ocfs2_filesys *fs, uint32_t cpos)
 {
 	errcode_t ret;
 	int val;
 
-	ret = ocfs2_bitmap_test(bitmap, bit, &val);
+	ret = ocfs2_test_cluster_allocated(fs, cpos, &val);
 	if (ret)
 		goto bail;
 
@@ -139,35 +113,18 @@ errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
 	errcode_t ret = 0;
 	char *buf = NULL;
 	uint64_t bm_blk, *blkno = blocks;
-	int val, loaded = 0;
 	uint32_t cluster, bpc = fs->fs_clustersize / fs->fs_blocksize;
 
 	if (!len || !blocks || !*blocks)
 		goto bail;
 	len = ocfs2_min(len,(size_t)OCFS2_MAX_BACKUP_SUPERBLOCKS);
 
-	if (!fs->fs_cluster_alloc) {
-		loaded = 1;
-		ret = ocfs2_lookup_system_inode(fs, GLOBAL_BITMAP_SYSTEM_INODE,
-						0, &bm_blk);
-		if (ret)
-			goto bail;
-
-		ret = ocfs2_read_cached_inode(fs, bm_blk, &fs->fs_cluster_alloc);
-		if (ret)
-			goto bail;
-
-		ret = ocfs2_load_chain_allocator(fs, fs->fs_cluster_alloc);
-		if (ret)
-			goto bail;
-	}
-
 	if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
 				      OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
 		/* check all the blkno to see whether it is used. */
 		for (i = 0; i < len; i++, blkno++) {
-			ret = check_cluster(fs->fs_cluster_alloc->ci_chains,
-					ocfs2_blocks_to_clusters(fs, *blkno));
+			ret = check_cluster(fs,
+					    ocfs2_blocks_to_clusters(fs, *blkno));
 			if (ret)
 				goto bail;
 		}
@@ -191,20 +148,14 @@ errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
 	if (ret)
 		goto bail;
 
+	/* We just tested the clusters, so the allocation can't fail */
 	blkno = blocks;
 	for (i = 0; i < len; i++, blkno++)
-		ocfs2_bitmap_set(fs->fs_cluster_alloc->ci_chains,
-				 ocfs2_blocks_to_clusters(fs, *blkno), &val);
-
-	ret = ocfs2_write_chain_allocator(fs, fs->fs_cluster_alloc);
+		ocfs2_new_specific_cluster(fs, ocfs2_blocks_to_clusters(fs, *blkno));
 
 bail:
 	if (buf)
 		ocfs2_free(&buf);
-	if (fs->fs_cluster_alloc && loaded) {
-		ocfs2_free_cached_inode(fs, fs->fs_cluster_alloc);
-		fs->fs_cluster_alloc = NULL;
-	}
 	return ret;
 }
 
-- 
1.5.6.5




More information about the Ocfs2-tools-devel mailing list