[Ocfs2-tools-devel] [PATCH 12/50] ocfs2: Decrement refcount when truncating refcounted extents.

Tao Ma tao.ma at oracle.com
Mon Jan 11 07:30:58 PST 2010


Add 'Decrement refcount for delete' in to the normal truncate
process. So for a refcounted extent record, call refcount rec
decrementation instead of cluster free.

Note:
Some xattr truncate functions have to be changed to pass
inode number into truncate so that we can find the proper
refcount tree.

Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
 include/ocfs2/ocfs2.h        |    2 +-
 libocfs2/truncate.c          |   31 +++++++++++++++++++++++++++++--
 tunefs.ocfs2/feature_xattr.c |   17 +++++++++--------
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 0af90c4..5208cb8 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -1349,7 +1349,7 @@ errcode_t ocfs2_read_xattr_bucket(ocfs2_filesys *fs,
 errcode_t ocfs2_write_xattr_bucket(ocfs2_filesys *fs,
 				   uint64_t blkno,
 				   char *bucket_buf);
-errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs,
+errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs, uint64_t ino,
 				     struct ocfs2_xattr_value_root *xv);
 errcode_t ocfs2_xattr_tree_truncate(ocfs2_filesys *fs,
 				    struct ocfs2_xattr_tree_root *xt);
diff --git a/libocfs2/truncate.c b/libocfs2/truncate.c
index 680fca5..16119a6 100644
--- a/libocfs2/truncate.c
+++ b/libocfs2/truncate.c
@@ -30,9 +30,11 @@
 #include <unistd.h>
 #endif
 
+#include <assert.h>
 #include "ocfs2/ocfs2.h"
 
 struct truncate_ctxt {
+	uint64_t ino;
 	uint64_t new_size_in_clusters;
 	uint32_t new_i_clusters;
 	errcode_t (*free_clusters)(ocfs2_filesys *fs,
@@ -42,6 +44,23 @@ struct truncate_ctxt {
 	void *free_data;
 };
 
+static int ocfs2_truncate_clusters(ocfs2_filesys *fs,
+				   struct ocfs2_extent_rec *rec,
+				   uint64_t ino,
+				   uint32_t len,
+				   uint64_t start)
+{
+	if (!ocfs2_refcount_tree(OCFS2_RAW_SB(fs->fs_super)) ||
+	    !(rec->e_flags & OCFS2_EXT_REFCOUNTED))
+		return ocfs2_free_clusters(fs, len, start);
+
+	assert(ino);
+
+	return ocfs2_decrease_refcount(fs, ino,
+				ocfs2_blocks_to_clusters(fs, start),
+				len, 1);
+}
+
 /*
  * Delete and free clusters if needed.  This only works with DEPTH_TRAVERSE.
  */
@@ -129,7 +148,8 @@ static int truncate_iterate(ocfs2_filesys *fs,
 			ret = ctxt->free_clusters(fs, len, start,
 						  ctxt->free_data);
 		else
-			ret = ocfs2_free_clusters(fs, len, start);
+			ret = ocfs2_truncate_clusters(fs, rec, ctxt->ino,
+						      len, start);
 		if (ret)
 			goto bail;
 		ctxt->new_i_clusters -= len;
@@ -213,6 +233,7 @@ static errcode_t ocfs2_zero_tail_and_truncate_full(ocfs2_filesys *fs,
 	struct truncate_ctxt ctxt;
 
 	new_size_in_blocks = ocfs2_blocks_in_bytes(fs, new_i_size);
+	ctxt.ino = ci->ci_blkno;
 	ctxt.new_i_clusters = ci->ci_inode->i_clusters;
 	ctxt.new_size_in_clusters =
 			ocfs2_clusters_in_blocks(fs, new_size_in_blocks);
@@ -299,13 +320,14 @@ errcode_t ocfs2_truncate(ocfs2_filesys *fs, uint64_t ino, uint64_t new_i_size)
 	return ocfs2_truncate_full(fs, ino, new_i_size, NULL, NULL);
 }
 
-errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs,
+errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs, uint64_t ino,
 				     struct ocfs2_xattr_value_root *xv)
 {
 	struct truncate_ctxt ctxt;
 	int changed;
 	struct ocfs2_extent_list *el = &xv->xr_list;
 
+	ctxt.ino = ino;
 	ctxt.new_i_clusters = xv->xr_clusters;
 	ctxt.new_size_in_clusters = 0;
 
@@ -322,6 +344,11 @@ errcode_t ocfs2_xattr_tree_truncate(ocfs2_filesys *fs,
 	int changed;
 	struct ocfs2_extent_list *el = &xt->xt_list;
 
+	/*
+	 * ino is used to find refcount tree, as we never use refcount
+	 * in xattr tree, so set it to 0.
+	 */
+	ctxt.ino = 0;
 	ctxt.new_i_clusters = xt->xt_clusters;
 	ctxt.new_size_in_clusters = 0;
 
diff --git a/tunefs.ocfs2/feature_xattr.c b/tunefs.ocfs2/feature_xattr.c
index 8eef7df..ebe75e3 100644
--- a/tunefs.ocfs2/feature_xattr.c
+++ b/tunefs.ocfs2/feature_xattr.c
@@ -51,7 +51,7 @@ static void empty_xattr_context(struct xattr_context *ctxt)
 	}
 }
 
-static errcode_t remove_xattr_entry(ocfs2_filesys *fs,
+static errcode_t remove_xattr_entry(ocfs2_filesys *fs, uint64_t ino,
 				    struct ocfs2_xattr_header *xh)
 {
 	int i;
@@ -65,7 +65,7 @@ static errcode_t remove_xattr_entry(ocfs2_filesys *fs,
 				(struct ocfs2_xattr_value_root *)
 				((void *)xh + xe->xe_name_offset +
 				OCFS2_XATTR_SIZE(xe->xe_name_len));
-			ret = ocfs2_xattr_value_truncate(fs, xv);
+			ret = ocfs2_xattr_value_truncate(fs, ino, xv);
 			if (ret)
 				break;
 		}
@@ -75,6 +75,7 @@ static errcode_t remove_xattr_entry(ocfs2_filesys *fs,
 }
 
 static errcode_t remove_xattr_buckets(ocfs2_filesys *fs,
+				      uint64_t ino,
 				      uint64_t blkno,
 				      uint32_t clusters)
 {
@@ -109,7 +110,7 @@ static errcode_t remove_xattr_buckets(ocfs2_filesys *fs,
 		if (i == 0)
 			num_buckets = xh->xh_num_buckets;
 
-		ret = remove_xattr_entry(fs, xh);
+		ret = remove_xattr_entry(fs, ino, xh);
 		if (ret)
 			break;
 	}
@@ -121,7 +122,7 @@ out:
 }
 
 
-static errcode_t remove_xattr_index_block(ocfs2_filesys *fs,
+static errcode_t remove_xattr_index_block(ocfs2_filesys *fs, uint64_t ino,
 					  struct ocfs2_xattr_block *xb)
 {
 	struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list;
@@ -141,7 +142,7 @@ static errcode_t remove_xattr_index_block(ocfs2_filesys *fs,
 			goto out;
 		}
 
-		ret = remove_xattr_buckets(fs, p_blkno, num_clusters);
+		ret = remove_xattr_buckets(fs, ino, p_blkno, num_clusters);
 		if (ret) {
 			tcom_err(ret, "while iterating bucket"
 				 " of extended attributes ");
@@ -184,14 +185,14 @@ static errcode_t remove_xattr_block(ocfs2_filesys *fs,
 	if (!(xb->xb_flags & OCFS2_XATTR_INDEXED)) {
 		struct ocfs2_xattr_header *xh = &xb->xb_attrs.xb_header;
 
-		ret = remove_xattr_entry(fs, xh);
+		ret = remove_xattr_entry(fs, di->i_blkno, xh);
 		if (ret) {
 			tcom_err(ret, "while trying to remove extended"
 				 " attributes in external block ");
 			goto out;
 		}
 	} else {
-		ret = remove_xattr_index_block(fs, xb);
+		ret = remove_xattr_index_block(fs, di->i_blkno, xb);
 		if (ret) {
 			tcom_err(ret, "while trying to remove extended"
 				 " attributes in index block ");
@@ -229,7 +230,7 @@ static errcode_t remove_xattr_ibody(ocfs2_filesys *fs,
 		 ((void *)di + fs->fs_blocksize -
 		  di->i_xattr_inline_size);
 
-	ret = remove_xattr_entry(fs, xh);
+	ret = remove_xattr_entry(fs, di->i_blkno, xh);
 	if (ret) {
 		tcom_err(ret, "while trying to remove extended"
 			 " attributes in ibody ");
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list