[Ocfs2-tools-devel] [PATCH 6/6] Add read write support for unwritten extents.

Tao Ma tao.ma at oracle.com
Mon Sep 24 02:21:15 PDT 2007


Modify ocfs2_file_write and ocfs2_file_read to be
compatible with unwritten extents.

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

diff --git a/libocfs2/fileio.c b/libocfs2/fileio.c
index ab1fe0b..85730b2 100644
--- a/libocfs2/fileio.c
+++ b/libocfs2/fileio.c
@@ -133,6 +133,7 @@ errcode_t ocfs2_file_read(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 	uint64_t	p_blkno;
 	uint32_t	tmp;
 	uint64_t	num_blocks;
+	uint16_t	extent_flags;
 
 	/* o_direct requires aligned io */
 	tmp = fs->fs_blocksize - 1;
@@ -156,15 +157,18 @@ errcode_t ocfs2_file_read(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 	while(wanted_blocks) {
 		ret = ocfs2_extent_map_get_blocks(ci, v_blkno, 1,
 						  &p_blkno, &contig_blocks,
-						  NULL);
+						  &extent_flags);
 		if (ret)
 			return ret;
 
 		if (contig_blocks > wanted_blocks)
 			contig_blocks = wanted_blocks;
 
-		if (!p_blkno) {
-			/* we meet with a hole, just empty the content.*/
+		if (!p_blkno || extent_flags & OCFS2_EXT_UNWRITTEN) {
+			/*
+			 * we meet with a hole or an unwritten extent,
+			 * so just empty the content.
+			 */
 			memset(ptr, 0, contig_blocks * fs->fs_blocksize);
 		} else {
 			ret = io_read_block(fs->fs_io, p_blkno,
@@ -232,7 +236,8 @@ errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 	uint32_t	wanted_blocks;
 	uint64_t	contig_blocks;
 	uint64_t	v_blkno;
-	uint64_t	p_blkno, p_alloc, p_offset = 0;
+	uint64_t	p_blkno, p_start, p_end;
+	uint64_t	begin_blocks = 0, end_blocks = 0;
 	uint32_t	tmp;
 	uint64_t	num_blocks;
 	int		bs_bits = OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
@@ -240,6 +245,7 @@ errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 	uint32_t	n_clusters, cluster_begin, cluster_end;
 	uint64_t	bpc = fs->fs_clustersize/fs->fs_blocksize;
 	int		insert = 0;
+	uint16_t	extent_flags = 0;
 
 	/* o_direct requires aligned io */
 	tmp = fs->fs_blocksize - 1;
@@ -262,13 +268,16 @@ errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 	while(wanted_blocks) {
 		ret = ocfs2_extent_map_get_blocks(ci, v_blkno, 1,
 						  &p_blkno, &contig_blocks,
-						  NULL);
+						  &extent_flags);
 		if (ret)
 			return ret;
 
 		if (contig_blocks > wanted_blocks)
 			contig_blocks = wanted_blocks;
 
+		begin_blocks = 0;
+		end_blocks = 0;
+		p_end = 0;
 	 	if (!p_blkno) {
 			/*
 			 * We meet with a hole here, so we allocate clusters
@@ -283,37 +292,47 @@ errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 			cluster_end = ocfs2_blocks_to_clusters(fs,
 						v_blkno + contig_blocks -1);
 			n_clusters = cluster_end - cluster_begin + 1;
-			ret = ocfs2_new_clusters(fs, 1, n_clusters, &p_alloc,
+			ret = ocfs2_new_clusters(fs, 1, n_clusters, &p_start,
 						 &n_clusters);
 			if (ret || n_clusters == 0)
 				return ret;
-
-			p_offset = v_blkno & (bpc - 1);
-			p_blkno = p_alloc + p_offset;
-			if (p_offset) {
-				/*
-				 * The user don't write the first blocks,
-				 * so we have to clear them.
-				 */
-				ret = empty_blocks(fs, p_alloc, p_offset);
-				if (ret)
-					return ret;
-			}
-
-			contig_blocks = n_clusters * bpc - p_offset;
+			
+			begin_blocks = v_blkno & (bpc - 1);
+			p_blkno = p_start + begin_blocks;
+			contig_blocks = n_clusters * bpc - begin_blocks;
 			if (contig_blocks > wanted_blocks) {
-				/*
-				 * we don't need to write that many blocks,
-				 * so empty the blocks at the bottom.
-				 */
-				ret = empty_blocks(fs, p_blkno + wanted_blocks,
-						contig_blocks - wanted_blocks);
-				if (ret)
-					return ret;
+				end_blocks = contig_blocks - wanted_blocks;
 				contig_blocks = wanted_blocks;
+				p_end = p_blkno + wanted_blocks;
 			}
 
 			insert = 1;
+		} else if (extent_flags & OCFS2_EXT_UNWRITTEN) {
+			begin_blocks = v_blkno & (bpc - 1);
+			p_start = p_blkno - begin_blocks;
+			p_end = p_blkno + wanted_blocks;
+			end_blocks = (p_end & (bpc - 1)) ? 
+						 bpc - (p_end & (bpc - 1 )) : 0;
+		}
+
+		if (begin_blocks) {
+			/*
+			 * The user don't write the first blocks,
+			 * so we have to empty them.
+			 */
+			ret = empty_blocks(fs, p_start, begin_blocks);
+			if (ret)
+				return ret;
+		}
+
+		if (end_blocks) {
+			/*
+			 * we don't need to write that many blocks,
+			 * so empty the blocks at the bottom.
+			 */
+			ret = empty_blocks(fs, p_end, end_blocks);
+			if (ret)
+				return ret;
 		}
 
 		ret = io_write_block(fs->fs_io, p_blkno, contig_blocks, ptr);
@@ -323,14 +342,14 @@ errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 		if (insert) {
 	 		ret = ocfs2_insert_extent(fs, ci->ci_blkno,
 					ocfs2_blocks_to_clusters(fs,v_blkno),
-					p_alloc, n_clusters, 0);
+					p_start, n_clusters, 0);
 			if (ret) {
 				/*
 				 * XXX: We don't wan't to overwrite the error
 				 * from insert_extent().  But we probably need
 				 * to BE LOUDLY UPSET.
 				 */
-				ocfs2_free_clusters(fs, n_clusters, p_alloc);
+				ocfs2_free_clusters(fs, n_clusters, p_start);
 				return ret;
 			}
 
@@ -344,12 +363,24 @@ errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 			ret = ocfs2_extent_map_get_blocks(ci, v_blkno, 1,
 						&p_blkno, NULL, NULL);
 			/* now we shouldn't find a hole. */
-			if (!p_blkno || p_blkno != p_alloc + p_offset)
+			if (!p_blkno || p_blkno != p_start + begin_blocks)
 				ret = OCFS2_ET_INTERNAL_FAILURE;
 			if (ret)
 				return ret;
 
 			insert = 0;
+		} else if (extent_flags & OCFS2_EXT_UNWRITTEN) {
+			cluster_begin = ocfs2_blocks_to_clusters(fs, v_blkno);
+			cluster_end = ocfs2_blocks_to_clusters(fs,
+						v_blkno + contig_blocks -1);
+			n_clusters = cluster_end - cluster_begin + 1;
+			ret = ocfs2_mark_extent_written(fs, ci->ci_inode,
+					cluster_begin, n_clusters,
+					p_blkno & ~(bpc - 1));
+			if (ret)
+				return ret;
+			ocfs2_free_cached_inode(fs, ci);
+			ocfs2_read_cached_inode(fs,ino, &ci);
 		}
 
 		*wrote += (contig_blocks << bs_bits);
-- 
1.5.3.2.g4f337



More information about the Ocfs2-tools-devel mailing list