[Ocfs2-tools-devel] [patch 07/11] Modify file read and write.
Mark Fasheh
mark.fasheh at oracle.com
Thu Aug 16 17:45:41 PDT 2007
On Thu, Aug 16, 2007 at 01:55:47AM +0800, tao.ma wrote:
> 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;
> + }
Ok, you're zeroing the entire cluster, and doing it before inserting the
extent - this is great. I'm not so fond of the double write though - later
on in this function, the users data will be re-written to some of the same
area. Can you please write the data and only zero the blocks outside of the
user request, but still preserve the ordering with respect to
ocfs2_insert_extent?
--Mark
--
Mark Fasheh
Senior Software Developer, Oracle
mark.fasheh at oracle.com
More information about the Ocfs2-tools-devel
mailing list