]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/ocfs2-Make-high-level-btree-extend-co.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / ocfs2-Make-high-level-btree-extend-co.patch
1 From: Tao Ma <tao.ma@oracle.com>
2 Subject: [PATCH 04/16] ocfs2: Make high level btree extend code generic
3 Patch-mainline: 2.6.28?
4 References: FATE302067
5
6 Factor out the non-inode specifics of ocfs2_do_extend_allocation() into a more generic
7 function, ocfs2_do_cluster_allocation(). ocfs2_do_extend_allocation calls
8 ocfs2_do_cluster_allocation() now, but the latter can be used for other
9 btree types as well.
10
11 Signed-off-by: Tao Ma <tao.ma@oracle.com>
12 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
13 ---
14 fs/ocfs2/alloc.c | 110 ++++++++++++++++++++++++++++++++++++++++++++
15 fs/ocfs2/alloc.h | 17 ++++++
16 fs/ocfs2/aops.c | 8 +--
17 fs/ocfs2/dir.c | 6 +-
18 fs/ocfs2/file.c | 136 ++++++++++---------------------------------------------
19 fs/ocfs2/file.h | 26 ++++------
20 fs/ocfs2/namei.c | 8 +--
21 7 files changed, 176 insertions(+), 135 deletions(-)
22
23 --- a/fs/ocfs2/alloc.c
24 +++ b/fs/ocfs2/alloc.c
25 @@ -4302,6 +4302,116 @@ bail:
26 return status;
27 }
28
29 +/*
30 + * Allcate and add clusters into the extent b-tree.
31 + * The new clusters(clusters_to_add) will be inserted at logical_offset.
32 + * The extent b-tree's root is root_el and it should be in root_bh, and
33 + * it is not limited to the file storage. Any extent tree can use this
34 + * function if it implements the proper ocfs2_extent_tree.
35 + */
36 +int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
37 + struct inode *inode,
38 + u32 *logical_offset,
39 + u32 clusters_to_add,
40 + int mark_unwritten,
41 + struct buffer_head *root_bh,
42 + struct ocfs2_extent_list *root_el,
43 + handle_t *handle,
44 + struct ocfs2_alloc_context *data_ac,
45 + struct ocfs2_alloc_context *meta_ac,
46 + enum ocfs2_alloc_restarted *reason_ret,
47 + enum ocfs2_extent_tree_type type)
48 +{
49 + int status = 0;
50 + int free_extents;
51 + enum ocfs2_alloc_restarted reason = RESTART_NONE;
52 + u32 bit_off, num_bits;
53 + u64 block;
54 + u8 flags = 0;
55 +
56 + BUG_ON(!clusters_to_add);
57 +
58 + if (mark_unwritten)
59 + flags = OCFS2_EXT_UNWRITTEN;
60 +
61 + free_extents = ocfs2_num_free_extents(osb, inode, root_bh, type);
62 + if (free_extents < 0) {
63 + status = free_extents;
64 + mlog_errno(status);
65 + goto leave;
66 + }
67 +
68 + /* there are two cases which could cause us to EAGAIN in the
69 + * we-need-more-metadata case:
70 + * 1) we haven't reserved *any*
71 + * 2) we are so fragmented, we've needed to add metadata too
72 + * many times. */
73 + if (!free_extents && !meta_ac) {
74 + mlog(0, "we haven't reserved any metadata!\n");
75 + status = -EAGAIN;
76 + reason = RESTART_META;
77 + goto leave;
78 + } else if ((!free_extents)
79 + && (ocfs2_alloc_context_bits_left(meta_ac)
80 + < ocfs2_extend_meta_needed(root_el))) {
81 + mlog(0, "filesystem is really fragmented...\n");
82 + status = -EAGAIN;
83 + reason = RESTART_META;
84 + goto leave;
85 + }
86 +
87 + status = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
88 + clusters_to_add, &bit_off, &num_bits);
89 + if (status < 0) {
90 + if (status != -ENOSPC)
91 + mlog_errno(status);
92 + goto leave;
93 + }
94 +
95 + BUG_ON(num_bits > clusters_to_add);
96 +
97 + /* reserve our write early -- insert_extent may update the inode */
98 + status = ocfs2_journal_access(handle, inode, root_bh,
99 + OCFS2_JOURNAL_ACCESS_WRITE);
100 + if (status < 0) {
101 + mlog_errno(status);
102 + goto leave;
103 + }
104 +
105 + block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
106 + mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
107 + num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
108 + status = ocfs2_insert_extent(osb, handle, inode, root_bh,
109 + *logical_offset, block, num_bits,
110 + flags, meta_ac, type);
111 + if (status < 0) {
112 + mlog_errno(status);
113 + goto leave;
114 + }
115 +
116 + status = ocfs2_journal_dirty(handle, root_bh);
117 + if (status < 0) {
118 + mlog_errno(status);
119 + goto leave;
120 + }
121 +
122 + clusters_to_add -= num_bits;
123 + *logical_offset += num_bits;
124 +
125 + if (clusters_to_add) {
126 + mlog(0, "need to alloc once more, wanted = %u\n",
127 + clusters_to_add);
128 + status = -EAGAIN;
129 + reason = RESTART_TRANS;
130 + }
131 +
132 +leave:
133 + mlog_exit(status);
134 + if (reason_ret)
135 + *reason_ret = reason;
136 + return status;
137 +}
138 +
139 static void ocfs2_make_right_split_rec(struct super_block *sb,
140 struct ocfs2_extent_rec *split_rec,
141 u32 cpos,
142 --- a/fs/ocfs2/alloc.h
143 +++ b/fs/ocfs2/alloc.h
144 @@ -41,6 +41,23 @@ int ocfs2_insert_extent(struct ocfs2_sup
145 u8 flags,
146 struct ocfs2_alloc_context *meta_ac,
147 enum ocfs2_extent_tree_type et_type);
148 +enum ocfs2_alloc_restarted {
149 + RESTART_NONE = 0,
150 + RESTART_TRANS,
151 + RESTART_META
152 +};
153 +int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
154 + struct inode *inode,
155 + u32 *logical_offset,
156 + u32 clusters_to_add,
157 + int mark_unwritten,
158 + struct buffer_head *root_bh,
159 + struct ocfs2_extent_list *root_el,
160 + handle_t *handle,
161 + struct ocfs2_alloc_context *data_ac,
162 + struct ocfs2_alloc_context *meta_ac,
163 + enum ocfs2_alloc_restarted *reason_ret,
164 + enum ocfs2_extent_tree_type type);
165 struct ocfs2_cached_dealloc_ctxt;
166 int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh,
167 handle_t *handle, u32 cpos, u32 len, u32 phys,
168 --- a/fs/ocfs2/aops.c
169 +++ b/fs/ocfs2/aops.c
170 @@ -1255,10 +1255,10 @@ static int ocfs2_write_cluster(struct ad
171 * any additional semaphores or cluster locks.
172 */
173 tmp_pos = cpos;
174 - ret = ocfs2_do_extend_allocation(OCFS2_SB(inode->i_sb), inode,
175 - &tmp_pos, 1, 0, wc->w_di_bh,
176 - wc->w_handle, data_ac,
177 - meta_ac, NULL);
178 + ret = ocfs2_add_inode_data(OCFS2_SB(inode->i_sb), inode,
179 + &tmp_pos, 1, 0, wc->w_di_bh,
180 + wc->w_handle, data_ac,
181 + meta_ac, NULL);
182 /*
183 * This shouldn't happen because we must have already
184 * calculated the correct meta data allocation required. The
185 --- a/fs/ocfs2/dir.c
186 +++ b/fs/ocfs2/dir.c
187 @@ -1383,9 +1383,9 @@ static int ocfs2_do_extend_dir(struct su
188 if (extend) {
189 u32 offset = OCFS2_I(dir)->ip_clusters;
190
191 - status = ocfs2_do_extend_allocation(OCFS2_SB(sb), dir, &offset,
192 - 1, 0, parent_fe_bh, handle,
193 - data_ac, meta_ac, NULL);
194 + status = ocfs2_add_inode_data(OCFS2_SB(sb), dir, &offset,
195 + 1, 0, parent_fe_bh, handle,
196 + data_ac, meta_ac, NULL);
197 BUG_ON(status == -EAGAIN);
198 if (status < 0) {
199 mlog_errno(status);
200 --- a/fs/ocfs2/file.c
201 +++ b/fs/ocfs2/file.c
202 @@ -488,7 +488,7 @@ bail:
203 }
204
205 /*
206 - * extend allocation only here.
207 + * extend file allocation only here.
208 * we'll update all the disk stuff, and oip->alloc_size
209 *
210 * expect stuff to be locked, a transaction started and enough data /
211 @@ -497,107 +497,25 @@ bail:
212 * Will return -EAGAIN, and a reason if a restart is needed.
213 * If passed in, *reason will always be set, even in error.
214 */
215 -int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
216 - struct inode *inode,
217 - u32 *logical_offset,
218 - u32 clusters_to_add,
219 - int mark_unwritten,
220 - struct buffer_head *fe_bh,
221 - handle_t *handle,
222 - struct ocfs2_alloc_context *data_ac,
223 - struct ocfs2_alloc_context *meta_ac,
224 - enum ocfs2_alloc_restarted *reason_ret)
225 +int ocfs2_add_inode_data(struct ocfs2_super *osb,
226 + struct inode *inode,
227 + u32 *logical_offset,
228 + u32 clusters_to_add,
229 + int mark_unwritten,
230 + struct buffer_head *fe_bh,
231 + handle_t *handle,
232 + struct ocfs2_alloc_context *data_ac,
233 + struct ocfs2_alloc_context *meta_ac,
234 + enum ocfs2_alloc_restarted *reason_ret)
235 {
236 - int status = 0;
237 - int free_extents;
238 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
239 - enum ocfs2_alloc_restarted reason = RESTART_NONE;
240 - u32 bit_off, num_bits;
241 - u64 block;
242 - u8 flags = 0;
243 -
244 - BUG_ON(!clusters_to_add);
245 -
246 - if (mark_unwritten)
247 - flags = OCFS2_EXT_UNWRITTEN;
248 -
249 - free_extents = ocfs2_num_free_extents(osb, inode, fe_bh,
250 - OCFS2_DINODE_EXTENT);
251 - if (free_extents < 0) {
252 - status = free_extents;
253 - mlog_errno(status);
254 - goto leave;
255 - }
256 -
257 - /* there are two cases which could cause us to EAGAIN in the
258 - * we-need-more-metadata case:
259 - * 1) we haven't reserved *any*
260 - * 2) we are so fragmented, we've needed to add metadata too
261 - * many times. */
262 - if (!free_extents && !meta_ac) {
263 - mlog(0, "we haven't reserved any metadata!\n");
264 - status = -EAGAIN;
265 - reason = RESTART_META;
266 - goto leave;
267 - } else if ((!free_extents)
268 - && (ocfs2_alloc_context_bits_left(meta_ac)
269 - < ocfs2_extend_meta_needed(&fe->id2.i_list))) {
270 - mlog(0, "filesystem is really fragmented...\n");
271 - status = -EAGAIN;
272 - reason = RESTART_META;
273 - goto leave;
274 - }
275 -
276 - status = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
277 - clusters_to_add, &bit_off, &num_bits);
278 - if (status < 0) {
279 - if (status != -ENOSPC)
280 - mlog_errno(status);
281 - goto leave;
282 - }
283 -
284 - BUG_ON(num_bits > clusters_to_add);
285 -
286 - /* reserve our write early -- insert_extent may update the inode */
287 - status = ocfs2_journal_access(handle, inode, fe_bh,
288 - OCFS2_JOURNAL_ACCESS_WRITE);
289 - if (status < 0) {
290 - mlog_errno(status);
291 - goto leave;
292 - }
293 -
294 - block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
295 - mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
296 - num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
297 - status = ocfs2_insert_extent(osb, handle, inode, fe_bh,
298 - *logical_offset, block, num_bits,
299 - flags, meta_ac, OCFS2_DINODE_EXTENT);
300 - if (status < 0) {
301 - mlog_errno(status);
302 - goto leave;
303 - }
304 + struct ocfs2_extent_list *el = &fe->id2.i_list;
305
306 - status = ocfs2_journal_dirty(handle, fe_bh);
307 - if (status < 0) {
308 - mlog_errno(status);
309 - goto leave;
310 - }
311 -
312 - clusters_to_add -= num_bits;
313 - *logical_offset += num_bits;
314 -
315 - if (clusters_to_add) {
316 - mlog(0, "need to alloc once more, clusters = %u, wanted = "
317 - "%u\n", fe->i_clusters, clusters_to_add);
318 - status = -EAGAIN;
319 - reason = RESTART_TRANS;
320 - }
321 -
322 -leave:
323 - mlog_exit(status);
324 - if (reason_ret)
325 - *reason_ret = reason;
326 - return status;
327 + return ocfs2_add_clusters_in_btree(osb, inode, logical_offset,
328 + clusters_to_add, mark_unwritten,
329 + fe_bh, el, handle,
330 + data_ac, meta_ac, reason_ret,
331 + OCFS2_DINODE_EXTENT);
332 }
333
334 static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
335 @@ -676,16 +594,16 @@ restarted_transaction:
336
337 prev_clusters = OCFS2_I(inode)->ip_clusters;
338
339 - status = ocfs2_do_extend_allocation(osb,
340 - inode,
341 - &logical_start,
342 - clusters_to_add,
343 - mark_unwritten,
344 - bh,
345 - handle,
346 - data_ac,
347 - meta_ac,
348 - &why);
349 + status = ocfs2_add_inode_data(osb,
350 + inode,
351 + &logical_start,
352 + clusters_to_add,
353 + mark_unwritten,
354 + bh,
355 + handle,
356 + data_ac,
357 + meta_ac,
358 + &why);
359 if ((status < 0) && (status != -EAGAIN)) {
360 if (status != -ENOSPC)
361 mlog_errno(status);
362 --- a/fs/ocfs2/file.h
363 +++ b/fs/ocfs2/file.h
364 @@ -31,6 +31,7 @@ extern const struct file_operations ocfs
365 extern const struct inode_operations ocfs2_file_iops;
366 extern const struct inode_operations ocfs2_special_file_iops;
367 struct ocfs2_alloc_context;
368 +enum ocfs2_alloc_restarted;
369
370 struct ocfs2_file_private {
371 struct file *fp_file;
372 @@ -38,21 +39,16 @@ struct ocfs2_file_private {
373 struct ocfs2_lock_res fp_flock;
374 };
375
376 -enum ocfs2_alloc_restarted {
377 - RESTART_NONE = 0,
378 - RESTART_TRANS,
379 - RESTART_META
380 -};
381 -int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
382 - struct inode *inode,
383 - u32 *logical_offset,
384 - u32 clusters_to_add,
385 - int mark_unwritten,
386 - struct buffer_head *fe_bh,
387 - handle_t *handle,
388 - struct ocfs2_alloc_context *data_ac,
389 - struct ocfs2_alloc_context *meta_ac,
390 - enum ocfs2_alloc_restarted *reason_ret);
391 +int ocfs2_add_inode_data(struct ocfs2_super *osb,
392 + struct inode *inode,
393 + u32 *logical_offset,
394 + u32 clusters_to_add,
395 + int mark_unwritten,
396 + struct buffer_head *fe_bh,
397 + handle_t *handle,
398 + struct ocfs2_alloc_context *data_ac,
399 + struct ocfs2_alloc_context *meta_ac,
400 + enum ocfs2_alloc_restarted *reason_ret);
401 int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size,
402 u64 zero_to);
403 int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
404 --- a/fs/ocfs2/namei.c
405 +++ b/fs/ocfs2/namei.c
406 @@ -1598,10 +1598,10 @@ static int ocfs2_symlink(struct inode *d
407 u32 offset = 0;
408
409 inode->i_op = &ocfs2_symlink_inode_operations;
410 - status = ocfs2_do_extend_allocation(osb, inode, &offset, 1, 0,
411 - new_fe_bh,
412 - handle, data_ac, NULL,
413 - NULL);
414 + status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0,
415 + new_fe_bh,
416 + handle, data_ac, NULL,
417 + NULL);
418 if (status < 0) {
419 if (status != -ENOSPC && status != -EINTR) {
420 mlog(ML_ERROR,