[Ocfs2-devel] [PATCH 19/41] ocfs2: Integrate CoW in file write.

Tao Ma tao.ma at oracle.com
Fri Aug 21 07:55:52 PDT 2009


Hi Joel,
	Here is the solution for refcounted+non-refcounted+refcounted issues.
	Please review.

Regards,
Tao

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;
+}
+
 int ocfs2_write_begin_nolock(struct address_space *mapping,
 			     loff_t pos, unsigned len, unsigned flags,
 			     struct page **pagep, void **fsdata,
@@ -1730,8 +1771,8 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 		BUG_ON(refcounted_cpos == UINT_MAX);
 		cow_len = wc->w_clen - (refcounted_cpos - wc->w_cpos);
 
-		ret = ocfs2_refcount_cow(inode, di_bh,
-					 refcounted_cpos, cow_len);
+		ret = ocfs2_refcount_clusters(inode, di_bh,
+					      refcounted_cpos, cow_len);
 		if (ret) {
 			mlog_errno(ret);
 			goto out;



More information about the Ocfs2-devel mailing list