]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/ocfs2-Make-high-level-btree-extend-co.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / ocfs2-Make-high-level-btree-extend-co.patch
CommitLineData
2cb7cef9
BS
1From: Tao Ma <tao.ma@oracle.com>
2Subject: [PATCH 04/16] ocfs2: Make high level btree extend code generic
3Patch-mainline: 2.6.28?
4References: FATE302067
5
6Factor out the non-inode specifics of ocfs2_do_extend_allocation() into a more generic
7function, ocfs2_do_cluster_allocation(). ocfs2_do_extend_allocation calls
8ocfs2_do_cluster_allocation() now, but the latter can be used for other
9btree types as well.
10
11Signed-off-by: Tao Ma <tao.ma@oracle.com>
12Signed-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,