[Ocfs2-tools-devel] [PATCH 15/50] liboocfs2: CoW a reflinked cluster when it is truncated.

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


When we truncate a file to a specific size which resides in a reflinked
cluster, we need to CoW it since we need to empty the spaces after
new_i_size.

Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
 libocfs2/truncate.c |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/libocfs2/truncate.c b/libocfs2/truncate.c
index 16119a6..d4f198c 100644
--- a/libocfs2/truncate.c
+++ b/libocfs2/truncate.c
@@ -175,6 +175,7 @@ static errcode_t ocfs2_zero_tail_for_truncate(ocfs2_cached_inode *ci,
 	ocfs2_filesys *fs = ci->ci_fs;
 	uint64_t start_blk, p_blkno, contig_blocks, start_off;
 	int count, byte_counts, bpc = fs->fs_clustersize /fs->fs_blocksize;
+	uint16_t ext_flags;
 
 	if (new_size == 0)
 		return 0;
@@ -182,7 +183,7 @@ static errcode_t ocfs2_zero_tail_for_truncate(ocfs2_cached_inode *ci,
 	start_blk = new_size / fs->fs_blocksize;
 
 	ret = ocfs2_extent_map_get_blocks(ci, start_blk, 1,
-					  &p_blkno, &contig_blocks, NULL);
+					  &p_blkno, &contig_blocks, &ext_flags);
 	if (ret)
 		goto out;
 
@@ -190,6 +191,22 @@ static errcode_t ocfs2_zero_tail_for_truncate(ocfs2_cached_inode *ci,
 	if (!p_blkno)
 		goto out;
 
+	if (ext_flags & OCFS2_EXT_REFCOUNTED) {
+		uint32_t cpos = ocfs2_blocks_to_clusters(fs, start_blk);
+		ret = ocfs2_refcount_cow(ci, cpos, 1, cpos + 1);
+		if (ret)
+			goto out;
+
+		ret = ocfs2_extent_map_get_blocks(ci, start_blk, 1,
+						  &p_blkno, &contig_blocks,
+						  &ext_flags);
+		if (ret)
+			goto out;
+
+		assert(!(ext_flags & OCFS2_EXT_REFCOUNTED) && p_blkno);
+
+	}
+
 	/* calculate the total blocks we need to empty. */
 	count = bpc - (p_blkno & (bpc - 1));
 	ret = ocfs2_malloc_blocks(fs->fs_io, count, &buf);
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list