[Ocfs2-devel] [PATCH 19/41] ocfs2: Integrate CoW in file write.
Joel Becker
Joel.Becker at oracle.com
Fri Aug 21 13:43:32 PDT 2009
On Fri, Aug 21, 2009 at 10:55:52PM +0800, Tao Ma wrote:
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index 02244bb..0978abe 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -1677,6 +1677,47 @@ static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos,
> return ret;
> }
>
> +/*
> + * CoW all refcounted clusters within [cow_start, cow_start + cow_len).
> + *
> + * Note: We may meet with non-refcounted clusters or even holes, just skip
> + * them and iterate until we reach cow_start + cow_len.
> + */
> +static int ocfs2_refcount_clusters(struct inode *inode,
> + struct buffer_head *di_bh,
> + u32 cow_start, u32 cow_len)
> +{
> + int ret = 0;
> + u32 p_cluster, num_clusters;
> + unsigned int ext_flags;
> +
> + while (cow_len) {
> + ret = ocfs2_get_clusters(inode, cow_start, &p_cluster,
> + &num_clusters, &ext_flags);
> + if (ret) {
> + mlog_errno(ret);
> + break;
> + }
> +
> + if (cow_len < num_clusters)
> + num_clusters = cow_len;
> +
> + if (ext_flags & OCFS2_EXT_REFCOUNTED) {
> + ret = ocfs2_refcount_cow(inode, di_bh, cow_start,
> + num_clusters);
> + if (ret) {
> + mlog_errno(ret);
> + break;
> + }
> + }
> +
> + cow_len -= num_clusters;
> + cow_start += num_clusters;
> + }
> +
> + return ret;
> +}
> +
This belongs in refcounttree.c and should be called
ocfs2_refcount_cow(). It should have the exact same prototype as
ocfs2_refcount_cow() does now. Inside this function the length should
be called write_len, not cow_len, because it's the length of the write
we're trying, not the length of the actual CoW. Rename
ocfs2_refcount_cow() to ocfs2_refcount_cow_hunk():
/*
* Starting at cpos, try to CoW write_len clusters. Don't CoW
* past max_cpos. This will stop when it runs into a hole or an
* unrefcounted extent.
*/
int ocfs2_refcount_cow_hunk(struct inode *inode,
struct buffer_head *di_bh,
u32 cpos, u32 write_len, u32 max_cpos);
/*
* CoW any and all clusters between cpos and cpos+write_len.
* Don't CoW past max_cpos. If this returns successfully, all
* clusters between cpos and cpos+write_len are safe to modify.
*/
int ocfs2_refcount_cow(struct inode *inode,
struct buffer_head *di_bh,
u32 cpos, u32 write_len, u32 max_cpos);
The idea is that any part of the ocfs2 code should be able to
call ocfs2_refcount_cow() for any cpos+write_len and be assured that the
clusters are writable when the function returns.
Joel
--
"The cynics are right nine times out of ten."
- H. L. Mencken
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
More information about the Ocfs2-devel
mailing list