[Ocfs2-tools-devel] [patch 07/11] Modify file read and write.take 2
tao.ma at oracle.com
tao.ma at oracle.com
Wed Aug 22 17:07:55 PDT 2007
Change ocfs2_file_read and ocfs2_file_write accordingly.
===================================================================
--- quilt.ocfs2-tools.orig/libocfs2/fileio.c 2007-08-21 06:38:06.000000000 -0400
+++ quilt.ocfs2-tools/libocfs2/fileio.c 2007-08-22 05:51:42.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,38 @@ errcode_t ocfs2_file_read(ocfs2_cached_i
return ret;
}
+/*
+ * Emtpy the blocks on the disk.
+ */
+static errcode_t empty_blocks(ocfs2_filesys *fs,
+ uint64_t start_blk,
+ uint64_t num_blocks)
+{
+ errcode_t ret;
+ char *buf = NULL;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
+ if (ret)
+ goto bail;
+
+ memset(buf, 0, fs->fs_blocksize);
+
+ while (num_blocks) {
+ ret = io_write_block(fs->fs_io, start_blk, 1, buf);
+ if (ret)
+ goto bail;
+
+ num_blocks--;
+ start_blk++;
+ }
+
+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 +229,15 @@ 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;
+ uint64_t empty_start, bpc = fs->fs_clustersize/fs->fs_blocksize;
/* o_direct requires aligned io */
tmp = fs->fs_blocksize - 1;
@@ -225,6 +266,68 @@ 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 = ocfs2_insert_extent(fs, ci->ci_blkno,
+ ocfs2_blocks_to_clusters(fs,v_blkno),
+ 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;
+ }
+
+ /*
+ * since the inode information has been changed, we
+ * may need to reinitialize it.
+ */
+ ocfs2_free_cached_inode(fs, ci);
+ ret = ocfs2_read_cached_inode(fs,ino, &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 (p_blkno & (bpc - 1)) {
+ /*
+ * The user don't write the first blocks,
+ * so we have to clear them.
+ */
+ empty_start = p_blkno & (~(bpc - 1));
+ ret = empty_blocks(fs, empty_start,
+ p_blkno - empty_start);
+ if (ret)
+ return ret;
+ }
+ if (contig_blocks > wanted_blocks) {
+ /*
+ * we don't need to write that many blocks,
+ * so empty the blocks at the bottom.
+ */
+ empty_start = p_blkno + wanted_blocks;
+ ret = empty_blocks(fs, empty_start,
+ contig_blocks - wanted_blocks);
+ if (ret)
+ return ret;
+ contig_blocks = wanted_blocks;
+ }
+ }
+
ret = io_write_block(fs->fs_io, p_blkno, contig_blocks, ptr);
if (ret)
return ret;
@@ -432,4 +535,3 @@ out:
return 0;
}
#endif /* DEBUG_EXE */
-
--
More information about the Ocfs2-tools-devel
mailing list