[Ocfs2-tools-devel] [PATCH 2/2] libocfs2: Add ocfs2_clear_backup_super_list()

Joel Becker Joel.Becker at oracle.com
Thu Jul 10 13:03:16 PDT 2008


The converse to ocfs2_set_backup_super_list() is needed to allow
disabling of backup superblocks.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 include/ocfs2/ocfs2.h   |    4 +++
 libocfs2/backup_super.c |   64 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index e2aa172..a6908c0 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -607,6 +607,10 @@ int ocfs2_get_backup_super_offsets(ocfs2_filesys *fs,
  */
 errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
 				      uint64_t *blocks, size_t len);
+/* Conversely, this clears all the allocator bits associated with the
+ * specified backup superblocks */
+errcode_t ocfs2_clear_backup_super_list(ocfs2_filesys *fs,
+					uint64_t *blocks, size_t len);
 
 /* Refresh the backup superblock information */
 errcode_t ocfs2_refresh_backup_supers(ocfs2_filesys *fs);
diff --git a/libocfs2/backup_super.c b/libocfs2/backup_super.c
index 54a1743..84b0449 100644
--- a/libocfs2/backup_super.c
+++ b/libocfs2/backup_super.c
@@ -54,6 +54,65 @@ int ocfs2_get_backup_super_offsets(ocfs2_filesys *fs,
 	return i;
 }
 
+errcode_t ocfs2_clear_backup_super_list(ocfs2_filesys *fs,
+					uint64_t *blocks, size_t len)
+{
+	size_t i;
+	errcode_t ret = 0;
+	uint64_t bm_blk;
+	int loaded = 0;
+
+	if (!len || !blocks || !*blocks)
+		goto bail;
+	len = ocfs2_min(len,(size_t)OCFS2_MAX_BACKUP_SUPERBLOCKS);
+
+	/*
+	 * Don't clear anything if backup superblocks aren't enabled -
+	 * there might be real data there!  If backup superblocks are
+	 * enabled, we know these blocks are backups, and we're
+	 * safe to clear them.
+	 */
+	if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
+				      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_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)
 {
 	errcode_t ret;
@@ -80,7 +139,7 @@ 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;
+	int val, loaded = 0;
 	uint32_t cluster, bpc = fs->fs_clustersize / fs->fs_blocksize;
 
 	if (!len || !blocks || !*blocks)
@@ -88,6 +147,7 @@ errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
 	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)
@@ -141,7 +201,7 @@ errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
 bail:
 	if (buf)
 		ocfs2_free(&buf);
-	if (fs->fs_cluster_alloc) {
+	if (fs->fs_cluster_alloc && loaded) {
 		ocfs2_free_cached_inode(fs, fs->fs_cluster_alloc);
 		fs->fs_cluster_alloc = NULL;
 	}
-- 
1.5.6


-- 

"There is no sincerer love than the love of food."  
         - George Bernard Shaw 

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127



More information about the Ocfs2-tools-devel mailing list