]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/ocfs2-initialize-the-cluster-we-re-writing-to.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / ocfs2-initialize-the-cluster-we-re-writing-to.patch
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
5 References: bnc#501563
6
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.
10
11 It handles clustersize > pagesize and blocksize < pagesize.
12
13 [Cleaned up by Joel Becker.]
14
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>
18 ---
19 fs/ocfs2/aops.c | 66 +++++++++++++++++++++++++++++++++++++++---------------
20 1 files changed, 47 insertions(+), 19 deletions(-)
21
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 {
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;