1 From e7432675f8ca868a4af365759a8d4c3779a3d922 Mon Sep 17 00:00:00 2001
2 From: Sunil Mushran <sunil.mushran@oracle.com>
3 Date: Thu, 6 Aug 2009 16:12:58 -0700
4 Subject: ocfs2: Initialize the cluster we're writing to in a non-sparse extend
7 In a non-sparse extend, we correctly allocate (and zero) the clusters between
8 the old_i_size and pos, but we don't zero the portions of the cluster we're
9 writing to outside of pos<->len.
11 It handles clustersize > pagesize and blocksize < pagesize.
13 [Cleaned up by Joel Becker.]
15 Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
16 Signed-off-by: Joel Becker <joel.becker@oracle.com>
17 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
19 fs/ocfs2/aops.c | 66 +++++++++++++++++++++++++++++++++++++++---------------
20 1 files changed, 47 insertions(+), 19 deletions(-)
22 Index: linux-2.6.27-ocfs2-update-sle11/fs/ocfs2/aops.c
23 ===================================================================
24 --- linux-2.6.27-ocfs2-update-sle11.orig/fs/ocfs2/aops.c
25 +++ linux-2.6.27-ocfs2-update-sle11/fs/ocfs2/aops.c
26 @@ -909,18 +909,17 @@ struct ocfs2_write_cluster_desc {
30 + unsigned c_needs_zero;
33 -static inline int ocfs2_should_zero_cluster(struct ocfs2_write_cluster_desc *d)
35 - return d->c_new || d->c_unwritten;
38 struct ocfs2_write_ctxt {
39 /* Logical cluster position / len of write */
43 + /* First cluster allocated in a nonsparse extend */
44 + u32 w_first_new_cpos;
46 struct ocfs2_write_cluster_desc w_desc[OCFS2_MAX_CLUSTERS_PER_PAGE];
49 @@ -998,6 +997,7 @@ static int ocfs2_alloc_write_ctxt(struct
52 wc->w_cpos = pos >> osb->s_clustersize_bits;
53 + wc->w_first_new_cpos = UINT_MAX;
54 cend = (pos + len - 1) >> osb->s_clustersize_bits;
55 wc->w_clen = cend - wc->w_cpos + 1;
57 @@ -1239,20 +1239,18 @@ out:
59 static int ocfs2_write_cluster(struct address_space *mapping,
60 u32 phys, unsigned int unwritten,
61 + unsigned int should_zero,
62 struct ocfs2_alloc_context *data_ac,
63 struct ocfs2_alloc_context *meta_ac,
64 struct ocfs2_write_ctxt *wc, u32 cpos,
65 loff_t user_pos, unsigned user_len)
67 - int ret, i, new, should_zero = 0;
70 struct inode *inode = mapping->host;
71 struct ocfs2_extent_tree et;
73 new = phys == 0 ? 1 : 0;
74 - if (new || unwritten)
80 @@ -1363,7 +1361,9 @@ static int ocfs2_write_cluster_by_desc(s
81 local_len = osb->s_clustersize - cluster_off;
83 ret = ocfs2_write_cluster(mapping, desc->c_phys,
84 - desc->c_unwritten, data_ac, meta_ac,
88 wc, desc->c_cpos, pos, local_len);
91 @@ -1413,14 +1413,14 @@ static void ocfs2_set_target_boundaries(
92 * newly allocated cluster.
94 desc = &wc->w_desc[0];
95 - if (ocfs2_should_zero_cluster(desc))
96 + if (desc->c_needs_zero)
97 ocfs2_figure_cluster_boundaries(osb,
102 desc = &wc->w_desc[wc->w_clen - 1];
103 - if (ocfs2_should_zero_cluster(desc))
104 + if (desc->c_needs_zero)
105 ocfs2_figure_cluster_boundaries(osb,
108 @@ -1488,13 +1488,28 @@ static int ocfs2_populate_write_desc(str
113 + * If w_first_new_cpos is < UINT_MAX, we have a non-sparse
114 + * file that got extended. w_first_new_cpos tells us
115 + * where the newly allocated clusters are so we can
118 + if (desc->c_cpos >= wc->w_first_new_cpos) {
120 + desc->c_needs_zero = 1;
126 + desc->c_needs_zero = 1;
127 *clusters_to_alloc = *clusters_to_alloc + 1;
129 - if (ext_flags & OCFS2_EXT_UNWRITTEN)
131 + if (ext_flags & OCFS2_EXT_UNWRITTEN) {
132 desc->c_unwritten = 1;
133 + desc->c_needs_zero = 1;
138 @@ -1654,10 +1669,13 @@ static int ocfs2_expand_nonsparse_inode(
139 if (newsize <= i_size_read(inode))
142 - ret = ocfs2_extend_no_holes(inode, newsize, newsize - len);
143 + ret = ocfs2_extend_no_holes(inode, newsize, pos);
147 + wc->w_first_new_cpos =
148 + ocfs2_clusters_for_bytes(inode->i_sb, i_size_read(inode));
153 @@ -1666,7 +1684,7 @@ int ocfs2_write_begin_nolock(struct addr
154 struct page **pagep, void **fsdata,
155 struct buffer_head *di_bh, struct page *mmap_page)
157 - int ret, credits = OCFS2_INODE_UPDATE_CREDITS;
158 + int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
159 unsigned int clusters_to_alloc, extents_to_split;
160 struct ocfs2_write_ctxt *wc;
161 struct inode *inode = mapping->host;
162 @@ -1744,8 +1762,19 @@ int ocfs2_write_begin_nolock(struct addr
166 - ocfs2_set_target_boundaries(osb, wc, pos, len,
167 - clusters_to_alloc + extents_to_split);
169 + * We have to zero sparse allocated clusters, unwritten extent clusters,
170 + * and non-sparse clusters we just extended. For non-sparse writes,
171 + * we know zeros will only be needed in the first and/or last cluster.
173 + if (clusters_to_alloc || extents_to_split ||
174 + wc->w_desc[0].c_needs_zero ||
175 + wc->w_desc[wc->w_clen - 1].c_needs_zero)
176 + cluster_of_pages = 1;
178 + cluster_of_pages = 0;
180 + ocfs2_set_target_boundaries(osb, wc, pos, len, cluster_of_pages);
182 handle = ocfs2_start_trans(osb, credits);
183 if (IS_ERR(handle)) {
184 @@ -1778,8 +1807,7 @@ int ocfs2_write_begin_nolock(struct addr
187 ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos,
188 - clusters_to_alloc + extents_to_split,
190 + cluster_of_pages, mmap_page);