]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.fixes/ocfs2-initialize-the-cluster-we-re-writing-to.patch
Change qemu to a version that support kvm and kqemu.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / ocfs2-initialize-the-cluster-we-re-writing-to.patch
CommitLineData
2cb7cef9
BS
1From e7432675f8ca868a4af365759a8d4c3779a3d922 Mon Sep 17 00:00:00 2001
2From: Sunil Mushran <sunil.mushran@oracle.com>
3Date: Thu, 6 Aug 2009 16:12:58 -0700
4Subject: ocfs2: Initialize the cluster we're writing to in a non-sparse extend
5References: bnc#501563
6
7In a non-sparse extend, we correctly allocate (and zero) the clusters between
8the old_i_size and pos, but we don't zero the portions of the cluster we're
9writing to outside of pos<->len.
10
11It handles clustersize > pagesize and blocksize < pagesize.
12
13[Cleaned up by Joel Becker.]
14
15Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
16Signed-off-by: Joel Becker <joel.becker@oracle.com>
17Signed-off-by: Mark Fasheh <mfasheh@suse.com>
18---
19 fs/ocfs2/aops.c | 66 +++++++++++++++++++++++++++++++++++++++---------------
20 1 files changed, 47 insertions(+), 19 deletions(-)
21
22Index: 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 {
27 */
28 unsigned c_new;
29 unsigned c_unwritten;
30+ unsigned c_needs_zero;
31 };
32
33-static inline int ocfs2_should_zero_cluster(struct ocfs2_write_cluster_desc *d)
34-{
35- return d->c_new || d->c_unwritten;
36-}
37-
38 struct ocfs2_write_ctxt {
39 /* Logical cluster position / len of write */
40 u32 w_cpos;
41 u32 w_clen;
42
43+ /* First cluster allocated in a nonsparse extend */
44+ u32 w_first_new_cpos;
45+
46 struct ocfs2_write_cluster_desc w_desc[OCFS2_MAX_CLUSTERS_PER_PAGE];
47
48 /*
49@@ -998,6 +997,7 @@ static int ocfs2_alloc_write_ctxt(struct
50 return -ENOMEM;
51
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;
56 get_bh(di_bh);
57@@ -1239,20 +1239,18 @@ out:
58 */
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)
66 {
67- int ret, i, new, should_zero = 0;
68+ int ret, i, new;
69 u64 v_blkno, p_blkno;
70 struct inode *inode = mapping->host;
71 struct ocfs2_extent_tree et;
72
73 new = phys == 0 ? 1 : 0;
74- if (new || unwritten)
75- should_zero = 1;
76-
77 if (new) {
78 u32 tmp_pos;
79
80@@ -1363,7 +1361,9 @@ static int ocfs2_write_cluster_by_desc(s
81 local_len = osb->s_clustersize - cluster_off;
82
83 ret = ocfs2_write_cluster(mapping, desc->c_phys,
84- desc->c_unwritten, data_ac, meta_ac,
85+ desc->c_unwritten,
86+ desc->c_needs_zero,
87+ data_ac, meta_ac,
88 wc, desc->c_cpos, pos, local_len);
89 if (ret) {
90 mlog_errno(ret);
91@@ -1413,14 +1413,14 @@ static void ocfs2_set_target_boundaries(
92 * newly allocated cluster.
93 */
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,
98 desc->c_cpos,
99 &wc->w_target_from,
100 NULL);
101
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,
106 desc->c_cpos,
107 NULL,
108@@ -1488,13 +1488,28 @@ static int ocfs2_populate_write_desc(str
109 phys++;
110 }
111
112+ /*
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
116+ * zero them.
117+ */
118+ if (desc->c_cpos >= wc->w_first_new_cpos) {
119+ BUG_ON(phys == 0);
120+ desc->c_needs_zero = 1;
121+ }
122+
123 desc->c_phys = phys;
124 if (phys == 0) {
125 desc->c_new = 1;
126+ desc->c_needs_zero = 1;
127 *clusters_to_alloc = *clusters_to_alloc + 1;
128 }
129- if (ext_flags & OCFS2_EXT_UNWRITTEN)
130+
131+ if (ext_flags & OCFS2_EXT_UNWRITTEN) {
132 desc->c_unwritten = 1;
133+ desc->c_needs_zero = 1;
134+ }
135
136 num_clusters--;
137 }
138@@ -1654,10 +1669,13 @@ static int ocfs2_expand_nonsparse_inode(
139 if (newsize <= i_size_read(inode))
140 return 0;
141
142- ret = ocfs2_extend_no_holes(inode, newsize, newsize - len);
143+ ret = ocfs2_extend_no_holes(inode, newsize, pos);
144 if (ret)
145 mlog_errno(ret);
146
147+ wc->w_first_new_cpos =
148+ ocfs2_clusters_for_bytes(inode->i_sb, i_size_read(inode));
149+
150 return ret;
151 }
152
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)
156 {
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
163
164 }
165
166- ocfs2_set_target_boundaries(osb, wc, pos, len,
167- clusters_to_alloc + extents_to_split);
168+ /*
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.
172+ */
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;
177+ else
178+ cluster_of_pages = 0;
179+
180+ ocfs2_set_target_boundaries(osb, wc, pos, len, cluster_of_pages);
181
182 handle = ocfs2_start_trans(osb, credits);
183 if (IS_ERR(handle)) {
184@@ -1778,8 +1807,7 @@ int ocfs2_write_begin_nolock(struct addr
185 * extent.
186 */
187 ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos,
188- clusters_to_alloc + extents_to_split,
189- mmap_page);
190+ cluster_of_pages, mmap_page);
191 if (ret) {
192 mlog_errno(ret);
193 goto out_quota;