[Ocfs2-tools-devel] [PATCH 38/50] libocfs2: Add ocfs2_change_refcount.

Tao Ma tao.ma at oracle.com
Mon Jan 11 07:31:24 PST 2010


In fsck.ocfs2, sometimes we need to change some clusters'
refcount in the refcount tree. So this patch adds
the function ocfs2_change_refcount.

We just add a new parameter 'value' to __ocfs2_increase_refcount
so that it can add any number or even decrease a refcount.

Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
 include/ocfs2/ocfs2.h |    3 ++
 libocfs2/refcount.c   |   50 ++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index c1954bb..2f24edd 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -436,6 +436,9 @@ errcode_t ocfs2_refcount_tree_get_rec(ocfs2_filesys *fs,
 				      uint32_t *num_clusters);
 errcode_t ocfs2_refcount_punch_hole(ocfs2_filesys *fs, uint64_t rf_blkno,
 				    uint64_t p_start, uint32_t len);
+errcode_t ocfs2_change_refcount(ocfs2_filesys *fs, uint64_t rf_blkno,
+				uint64_t p_start, uint32_t len,
+				uint32_t refcount);
 errcode_t ocfs2_swap_dir_entries_from_cpu(void *buf, uint64_t bytes);
 errcode_t ocfs2_swap_dir_entries_to_cpu(void *buf, uint64_t bytes);
 void ocfs2_swap_dir_trailer(struct ocfs2_dir_block_trailer *trailer);
diff --git a/libocfs2/refcount.c b/libocfs2/refcount.c
index 1218738..d8fe16e 100644
--- a/libocfs2/refcount.c
+++ b/libocfs2/refcount.c
@@ -1018,7 +1018,8 @@ out:
 
 static int __ocfs2_increase_refcount(ocfs2_filesys *fs,
 				     char *ref_root_buf,
-				     uint64_t cpos, uint32_t len, int merge)
+				     uint64_t cpos, uint32_t len, int merge,
+				     int value)
 {
 	int ret = 0, index;
 	char *ref_leaf_buf = NULL;
@@ -1053,11 +1054,11 @@ static int __ocfs2_increase_refcount(ocfs2_filesys *fs,
 		 */
 		if (rec.r_refcount && rec.r_cpos == cpos && set_len <= len) {
 			ret = ocfs2_change_refcount_rec(fs, ref_leaf_buf, index,
-							merge, 1);
+							merge, value);
 			if (ret)
 				goto out;
 		} else if (!rec.r_refcount) {
-			rec.r_refcount = 1;
+			rec.r_refcount = value;
 
 			ret = ocfs2_insert_refcount_rec(fs, ref_root_buf,
 							ref_leaf_buf,
@@ -1069,7 +1070,7 @@ static int __ocfs2_increase_refcount(ocfs2_filesys *fs,
 				      (uint64_t)(rec.r_cpos + set_len)) - cpos;
 			rec.r_cpos = cpos;
 			rec.r_clusters = set_len;
-			rec.r_refcount += 1;
+			rec.r_refcount += value;
 
 			ret = ocfs2_split_refcount_rec(fs, ref_root_buf,
 						       ref_leaf_buf,
@@ -1120,7 +1121,7 @@ errcode_t ocfs2_increase_refcount(ocfs2_filesys *fs, uint64_t ino,
 		goto out;
 
 	ret =  __ocfs2_increase_refcount(fs, ref_root_buf,
-					 cpos, len, 1);
+					 cpos, len, 1, 1);
 out:
 	if (ref_root_buf)
 		ocfs2_free(&ref_root_buf);
@@ -1946,6 +1947,45 @@ out:
 	return ret;
 }
 
+errcode_t ocfs2_change_refcount(ocfs2_filesys *fs, uint64_t rf_blkno,
+				uint64_t p_start, uint32_t len,
+				uint32_t refcount)
+{
+	errcode_t ret;
+	char *root_buf = NULL, *buf = NULL;
+	struct ocfs2_refcount_rec rec;
+	int index, value;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &root_buf);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_read_refcount_block(fs, rf_blkno, root_buf);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_get_refcount_rec(fs, root_buf, p_start,
+				     len, &rec, &index, buf);
+	assert(rec.r_refcount != refcount &&
+	       rec.r_cpos <= p_start &&
+	       rec.r_cpos + rec.r_clusters >= p_start + len);
+
+	value = refcount;
+	value -= rec.r_refcount;
+	ret = __ocfs2_increase_refcount(fs, root_buf, p_start, len,
+					1, value);
+out:
+	if (root_buf)
+		ocfs2_free(&root_buf);
+	if (buf)
+		ocfs2_free(&buf);
+	return ret;
+}
+
 struct xattr_value_obj {
 	errcode_t errcode;
 	uint64_t p_cpos;
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list