[Ocfs2-tools-devel] [patch 07/11] Modify file read and write.

tao.ma at oracle.com tao.ma at oracle.com
Wed Aug 15 10:55:47 PDT 2007


Change ocfs2_file_read and ocfs2_file_write accordingly.
===================================================================
--- test.ocfs2-tools.orig/libocfs2/fileio.c	2007-08-16 00:27:42.000000000 -0400
+++ test.ocfs2-tools/libocfs2/fileio.c	2007-08-16 00:36:28.000000000 -0400
@@ -128,7 +128,7 @@ errcode_t ocfs2_file_read(ocfs2_cached_i
 	errcode_t	ret = 0;
 	char		*ptr = (char *) buf;
 	uint32_t	wanted_blocks;
-	uint32_t	contig_blocks;
+	uint64_t	contig_blocks;
 	uint64_t	v_blkno;
 	uint64_t	p_blkno;
 	uint32_t	tmp;
@@ -162,9 +162,15 @@ errcode_t ocfs2_file_read(ocfs2_cached_i
 		if (contig_blocks > wanted_blocks)
 			contig_blocks = wanted_blocks;
 
-		ret = io_read_block(fs->fs_io, p_blkno, contig_blocks, ptr);
-		if (ret)
-			return ret;
+		if (!p_blkno) {
+			/* we meet with a hole, just empty the content.*/
+			memset(ptr, 0, contig_blocks * fs->fs_blocksize);
+		} else {
+			ret = io_read_block(fs->fs_io, p_blkno,
+					    contig_blocks, ptr);
+			if (ret)
+				return ret;
+		}
 
 		*got += (contig_blocks <<
 			 OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits);
@@ -184,6 +190,42 @@ errcode_t ocfs2_file_read(ocfs2_cached_i
 	return ret;
 }
 
+/*
+ * Emtpy the clusters on the disk.
+ *
+ * The "start_blk" is aligned with the cluster border since it is got by
+ * ocfs2_new_clusters.
+ */
+static errcode_t empty_clusters(ocfs2_filesys *fs,
+				uint64_t start_blk,
+				uint32_t num_clusters)
+{
+	errcode_t ret;
+	char *buf = NULL;
+	int bpc = fs->fs_clustersize / fs->fs_blocksize;
+
+	ret = ocfs2_malloc_blocks(fs->fs_io, bpc, &buf);
+	if (ret)
+		goto bail;
+
+	memset(buf, 0, fs->fs_clustersize);
+
+	while (num_clusters) {
+		ret = io_write_block(fs->fs_io, start_blk, bpc, buf);
+		if (ret)
+			goto bail;
+
+		num_clusters--;
+		start_blk += bpc;
+	}
+
+bail:
+	if (buf)
+		ocfs2_free(&buf);
+
+	return ret;
+}
+
 errcode_t ocfs2_file_write(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 			   uint64_t offset, uint32_t *wrote)
 {
@@ -191,12 +233,14 @@ errcode_t ocfs2_file_write(ocfs2_cached_
 	errcode_t	ret = 0;
 	char		*ptr = (char *) buf;
 	uint32_t	wanted_blocks;
-	uint32_t	contig_blocks;
+	uint64_t	contig_blocks;
 	uint64_t	v_blkno;
 	uint64_t	p_blkno;
 	uint32_t	tmp;
 	uint64_t	num_blocks;
 	int		bs_bits = OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+	uint64_t	ino = ci->ci_blkno;
+	uint32_t	n_clusters, cluster_begin, cluster_end;
 
 	/* o_direct requires aligned io */
 	tmp = fs->fs_blocksize - 1;
@@ -225,6 +269,50 @@ errcode_t ocfs2_file_write(ocfs2_cached_
 		if (contig_blocks > wanted_blocks)
 			contig_blocks = wanted_blocks;
 
+	 	if (!p_blkno) {
+			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_new_clusters(fs, 1, n_clusters, &p_blkno,
+						 &n_clusters);
+			if (ret)
+				return ret;
+
+			ret = empty_clusters(fs, p_blkno, n_clusters);
+			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_blkno);
+				return ret;
+			}
+
+	 		ret = ocfs2_insert_extent(fs, ci->ci_blkno,
+					ocfs2_blocks_to_clusters(fs,v_blkno),
+					p_blkno, n_clusters);
+			if (ret) {
+				ocfs2_free_clusters(fs, n_clusters, p_blkno);
+				return ret;
+			}
+
+			/* since the extent information has been changed, we
+			 * may need to reinitialize it. */
+			ocfs2_extent_map_free(ci);
+			ocfs2_free_cached_inode(fs, ci);
+			ret = ocfs2_read_cached_inode(fs,ino, &ci);
+			ocfs2_extent_map_init(fs,ci);
+			ret = ocfs2_extent_map_get_blocks(ci, v_blkno, 1,
+						&p_blkno, &contig_blocks);
+			/* now we shouldn't find a hole. */
+			if (!p_blkno && !ret)
+				ret = OCFS2_ET_INTERNAL_FAILURE;
+			if (ret)
+				return ret;
+			if (contig_blocks > wanted_blocks)
+				contig_blocks = wanted_blocks;
+		}
+
 		ret = io_write_block(fs->fs_io, p_blkno, contig_blocks, ptr);
 		if (ret)
 			return ret;
@@ -432,4 +520,3 @@ out:
 	return 0;
 }
 #endif  /* DEBUG_EXE */
-

-- 



More information about the Ocfs2-tools-devel mailing list